AndroidのTextViewを利用して単語ごとにアニメーションを表示することができます。
前言
AndroidのTextViewは、各テキストのアニメーションを設定することができません。TextSwitchを使っても、私の欲しい効果を実現するのは難しいです。
カスタムを選択します。大体の考えは:View Groupを継承して、Textを設定する時、各文字は一つのTextViewで、一つの固定時間ごとに、各TextViewのアニメーションを起動します。
CTextViewを定義し、View Groupを継承する:
主要コードを実装:
この方法は以下のように実現される。
以上はAndroidのTextViewを利用して単語ごとのアニメーションのすべての内容を実現して、実現した後に効果はやはりとてもすばらしくて、興味がある友達は自分で実践し始めるようにしましょう。疑問があればコメントして検討してもいいです。
AndroidのTextViewは、各テキストのアニメーションを設定することができません。TextSwitchを使っても、私の欲しい効果を実現するのは難しいです。
カスタムを選択します。大体の考えは:View Groupを継承して、Textを設定する時、各文字は一つのTextViewで、一つの固定時間ごとに、各TextViewのアニメーションを起動します。
CTextViewを定義し、View Groupを継承する:
主要コードを実装:
public class CTextView extends ViewGroup {
}
外部への方法はsetText(String text, final Animation animation, int duration)
であり、テキストは表示する文字列であり、アニメーションは各文字のアニメーションであり、durationは文字アニメーションの再生間隔である。この方法は以下のように実現される。
public void setText(String text, final Animation animation, int duration) {
int time = 0;
if(text != null && !text.isEmpty()) {
char[] characters = text.toCharArray();
for(char c : characters) {
final TextView t = new TextView(context);
// , TextView,
t.setText(String.valueOf(c));
t.setTextSize(28);
Handler h = new Handler();
// duration , TextView
h.postDelayed(new Runnable() {
@Override
public void run() {
addView(t);
t.setAnimation(animation);
}
}, time);
time += duration;
}
}
}
CTextViewの完全な実現は以下の通りである。
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.TextView;
/**
* Created by cchen on 2014/9/2.
*/
public class CTextView extends ViewGroup {
private Context context;
public CTextView(Context context) {
super(context);
this.context = context;
}
public CTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public CTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
public void setText(String text, final Animation animation, int duration) {
int time = 0;
if(text != null && !text.isEmpty()) {
char[] characters = text.toCharArray();
for(char c : characters) {
final TextView t = new TextView(context);
// , TextView,
t.setText(String.valueOf(c));
t.setTextSize(28);
Handler h = new Handler();
// duration , TextView
h.postDelayed(new Runnable() {
@Override
public void run() {
addView(t);
t.setAnimation(animation);
}
}, time);
time += duration;
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measureWidth = measureWidth(widthMeasureSpec);
int measureHeight = measureHeight(heightMeasureSpec);
// ViewGroup
measureChildren(widthMeasureSpec, heightMeasureSpec);
// MyViewGroup
setMeasuredDimension(measureWidth, measureHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childLeft = 0;
//
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
// onMeasure
int measureHeight = childView.getMeasuredHeight();
int measuredWidth = childView.getMeasuredWidth();
//
childView.layout(childLeft, 0, childLeft + measuredWidth, measureHeight);
childLeft += measuredWidth;
}
}
private int measureWidth(int pWidthMeasureSpec) {
int result = 0;
int widthMode = MeasureSpec.getMode(pWidthMeasureSpec);//
int widthSize = MeasureSpec.getSize(pWidthMeasureSpec);//
switch (widthMode) {
/**
* mode , MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY,
* MeasureSpec.AT_MOST。
*
*
* MeasureSpec.EXACTLY ,
* layout_width layout_height andorid
* :layout_width="50dip", FILL_PARENT , , 。
*
*
* MeasureSpec.AT_MOST ,
* layout_width layout_height WRAP_CONTENT
* , ,
* 。 , mode AT_MOST,size 。
*
*
* MeasureSpec.UNSPECIFIED , , AdapterView,
* measure 。
*/
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = widthSize;
break;
}
return result;
}
private int measureHeight(int pHeightMeasureSpec) {
int result = 0;
int heightMode = MeasureSpec.getMode(pHeightMeasureSpec);
int heightSize = MeasureSpec.getSize(pHeightMeasureSpec);
switch (heightMode) {
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = heightSize;
break;
}
return result;
}
}
その後、レイアウトファイルにカスタムコンポーネントを使用します。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".NetworkTestActivity">
<com.network.cchen.network.CTextView
android:id="@+id/cTextView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.network.cchen.network.CTextView>
</LinearLayout>
Activityでは、CTextViewのsetText
方法を呼び出し、関連パラメータを入力すれば良い。
import android.app.Activity;
import android.os.Bundle;
import android.view.animation.AnimationUtils;
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_network_test);
CTextView cTextView = (CTextView) findViewById(R.id.cTextView);
cTextView.setText("Hello world", AnimationUtils.loadAnimation(this, R.anim.myanim), 300);
}
}
二つ目のパラメータはアニメです。透明から不透明までの効果が欲しいです。myanim.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="1000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
文字を一つずつ実現したいなら、右から飛んできます。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fillAfter="true"
android:fromXDelta="50%p"
android:interpolator="@android:anim/anticipate_interpolator"
android:toXDelta="0" />
</set>
締め括りをつける以上はAndroidのTextViewを利用して単語ごとのアニメーションのすべての内容を実現して、実現した後に効果はやはりとてもすばらしくて、興味がある友達は自分で実践し始めるようにしましょう。疑問があればコメントして検討してもいいです。