安卓自定义View——(一:RaiseNumberAnimTextView 带数字增长动画的TextView)
2016-11-14 14:56
531 查看
前言
某些app上,新进入一个Activity的时候,上面的一个关键性数字(比如金额)会以一个数字不断变大的动画来显示。刚开始的时候,想到的一个方案是:使用Thead+Handler,给定一个动画总时长与刷新间隔时长,根据公式(数字从0开始,每次增长值为数组除以动画执行次数,动画执行次数等于动画总时长除以刷新间隔时长):// addValue 每次刷新时数值增加多少;number 最终要显示的数字 // alltime 动画执行总时长;gaptime 动画刷新时间间隔 addValue=number/(alltime/gaptime);
每隔一段时间重新设置TextView的字符串为增加后的值,直到动画结束显示最终结果。
其实对安卓动画有一定了解的应该都知道ValueAnimator这个类,我们可以使用它来很好的实现所要的效果,而不需要我们自己来生硬的控制隔多久就增加多少刷新显示。根据ValueAnimator的属性方法以及实际需要,我们封装一个自定义View来实现我们的需求:
能自定义设置动画持续时长。
能设置int型数字或float型数字。
能控制动画速率,如匀速增加、加速、减速、先加速后减速等。
能监听到动画正常的执行结束,调用后续方法。
跟随界面的生命周期,相应的执行动画的结束、暂停、继续等操作。
RaiseNumberAnimTextView代码
根据暂时的需求,RaiseNumberAnimTextView的代码如下所示,继承自TextView,所以它拥有TextView的所有属性以及方法,其他部分的介绍见注释:/** * API不能低于19。 * setDuration方法设置动画执行时长 * setNumberWithAnim方法调用时将会以递增动画显示数字出来 * setAnimEndListener方法设置监听动画正常执行结束 * setAnimInterpolator方法设置动画速率 * 在该View的Activity或Fragment的onDestroy方法中调用clearAnimator方法,onPause调用onPause,onResume调用onResume。 */ public class RaiseNumberAnimTextView extends TextView { private long mDuration = 1000; // 动画持续时间 ms,默认1s private ValueAnimator animator; private TimeInterpolator mTimeInterpolator = new LinearInterpolator(); // 动画速率 private AnimEndListener mEndListener; // 动画正常结束监听事件 public RaiseNumberAnimTextView(Context context) { super(context); } public RaiseNumberAnimTextView(Context context, AttributeSet attrs) { super(context, attrs); } public RaiseNumberAnimTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * 设置动画持续时间,默认为1s。需要在setNumberWithAnim之前设置才有效 * @param duration */ public void setDuration(long duration) { if (duration > 0) { mDuration = duration; } } /** * 设置动画速率,默认为LinearInterpolator。需要在setNumberWithAnim之前设置才有效 * @param timeInterpolator */ public void setAnimInterpolator(TimeInterpolator timeInterpolator) { mTimeInterpolator = timeInterpolator; } /** * 设置要显示的float数字,带动画显示 * @param number */ public void setNumberWithAnim(float number) { clearAnimator(); // 设置动画,float值的起始值 animator = ValueAnimator.ofFloat(0.0f, number); startAnimator(); } /** * 设置要显示的int数字,带动画显示。 * @param number */ public void setNumberWithAnim(int number) { clearAnimator(); // 设置动画,int值的起始值 animator = ValueAnimator.ofInt(0, number); startAnimator(); } // 清除动画 public void clearAnimator() { if (null != animator) { if (animator.isRunning()) { animator.removeAllListeners(); animator.removeAllUpdateListeners(); animator.cancel(); } animator = null; } } // 暂停动画 public void onPause() { if (null != animator && animator.isRunning()) { animator.pause(); // API 不低于19 } } // 继续执行动画 public void onResume() { if (null != animator && animator.isRunning()) { animator.resume(); } } // 设置时常与过程处理,启动动画 private void startAnimator() { if (null != animator) { animator.setDuration(mDuration); animator.setInterpolator(mTimeInterpolator); // 动画过程中获取当前值,显示 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { setText(valueAnimator.getAnimatedValue().toString()); } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { } @Override public void onAnimationEnd(Animator animator) { if (null != mEndListener) { // 动画不是中途取消,而是正常结束 mEndListener.onAnimFinish(); } } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } }); animator.start(); } } public void setAnimEndListener(AnimEndListener listener) { mEndListener = listener; } // 动画显示数字的结束监听,当动画结束显示正确的数字时,可能需要做些处理 public interface AnimEndListener { void onAnimFinish(); } }
需要注意的有两点:
1. 在界面的onDestroy方法中调用clearAnimator方法,关闭该View的动画,释放资源。测试发现,界面被关掉后,该View的动画与动画结束监听还在执行。
2. 在界面的onPause调用该View的onPause,onResume调用该View的onResume。但要注意,ValueAnimator的pause()方法要求api最低版本不能低于19。低版本中则需要自己去实现动画的暂停与继续效果。另外这里也说一下为什么要加这个动画的暂停与继续,假如进入界面显示这个数字,动画执行完之后我们要弹一个Toast或者弹出一个对话框,那么我们肯定不希望当我们进入了下一个界面的时候,动画才结束这个时候做出那些操作。如果没有这些顾虑的话,可以不做这个步骤。
测试验证
使用三个RaiseNumberAnimTextView来测试,第一个和第二个均设置显示1000000,且动画时长均为5s,第一个加速显示,第二个减速显示,且第一个添加动画正常结束的监听。第三个则使用默认的速率与动画时长,显示123456.78。且在执行动画时切换界面测试动画的暂停与继续。测试代码如下(onResume、onPause、onDestroy等方法代码省略,记得要加上):tvRaisenumber1.setAnimEndListener(new RaiseNumberAnimTextView.AnimEndListener() { @Override public void onAnimFinish() { ToastUtils.showToast("第一个数字的动画执行完了"); } }); // 测试更改值会不会异常 tvRaisenumber1.setDuration(1000 * 15); tvRaisenumber1.setNumberWithAnim(123456.95f); tvRaisenumber1.setDuration(1000 * 5); tvRaisenumber1.setAnimInterpolator(new AccelerateInterpolator()); tvRaisenumber1.setNumberWithAnim(1000000); tvRaisenumber2.setDuration(1000 * 5); tvRaisenumber2.setAnimInterpolator(new DecelerateInterpolator()); tvRaisenumber2.setNumberWithAnim(1000000); tvRaisenumber3.setNumberWithAnim(123456.78f);
经测试,运行正常。
相关文章推荐
- 自定义View实现自动数字增长的TextView
- android自定义TextView实现安卓手机开机android文字Log的动画效果
- Android TextView自定义数字滚动动画
- Android 自定义TextView 左右滑动实现数字自增长
- 安卓选择器类库,包括日期时间选择器、单项选择器、二三级联动选择器、地址选择器、颜色选择器、文件目录选择器、数字选择器等,可自定义顶部及底部界面,可自定义窗口动画。
- Android 自定义TextView实现文字渐变动画
- 安卓自定义View----实现TextView可设置drawable宽高度
- Android 自定义TextView实现文字渐变动画
- 安卓开发之自定义动画控件BatteryView(电池加载动画)
- NumberRunningTextView(数字会滚动的TextView)
- 安卓自定义view动画案例
- 安卓选择器类库,包括日期选择器、时间选择器、单项选择器、数字选择器、二三级联动选择器、省市区地址选择器、颜色选择器、文件目录选择器等,可自定义顶部及底部界面,可自定义窗口动画
- Android属性动画实现TextView类似支付宝余额数字滚动
- 自定义TextView/EditText,实现显示(或输入)小数、数字前缀(¥$...)、千分符、最大值等
- 实现安卓中TextView,EditText中数字的数码管字体显示
- 教你如何自定义数字会滚动的TextView
- 安卓自定义view,实现页面切换的位置指示动画
- 安卓自定义TextView实现签到效果
- Android进阶——自定义View之扩展系统控件的另一种思路实现渐变文字动画的TextView
- 安卓自定义界面——textview显示带小红点