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を利用して単語ごとのアニメーションのすべての内容を実現して、実現した後に効果はやはりとてもすばらしくて、興味がある友達は自分で実践し始めるようにしましょう。疑問があればコメントして検討してもいいです。