在安卓程序启动的时候,想逐字显示一段话,每个字都有一个从透明到不透明的渐变动画。Android的TextView只能设置整个TextView的动画,而不能设置每个文字的动画。即使是使用TextSwitcher,也很难实现我想要的效果。

 

所以选择自定义一个。大体思路是:继承ViewGroup,设置Text的时候,每个文字为一个TextView,每隔一个固定时间,启动每个TextView的动画。

 

定义一个CTextView,继承ViewGroup:实现主要代码:

public class CTextView extends ViewGroup {}

向外提供一个方法setText(String text, final Animation animation, int duration),text为要显示的字符串,animation为每个字符的动画,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;    }}

 然后在布局文件中使用该自定义组件:

        

 在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"?>     

 如果想实现文字逐个从右侧飞入:

<?xml version="1.0" encoding="utf-8"?>    

 

更多相关文章

  1. Android中的布局 Layout
  2. Android自定义控件系列九:从源码看Android触摸事件分发机制
  3. Android(安卓)AccessibilityService机制源码解析
  4. Android中Layout转成Java代码
  5. android使用透明色
  6. [android] 解决DatePickerDialog和TimePickerDialog控件取消按钮
  7. android之复选框点击事件(掌握CheckBox复选控件)
  8. Android(安卓)listview的使用
  9. Android硬件加速的一些问题和错误

随机推荐

  1. android权限列表
  2. android下载系统版本步骤(通过SecureCRT)
  3. Android(安卓)WebView 软键盘遮挡输入框
  4. android 画图------类似跑马灯的效果
  5. android6.0源码分析之AMS服务源码分析
  6. Android(安卓)如何添加一个apk使模拟器和
  7. Android(安卓)自定义View实现带进度的下
  8. Android应用开发——Activity组件
  9. 解决下载Android(安卓)Build-tools 19.1.
  10. Android之开源中国客户端源码分析(一)