今天我们自定义一个TextView,它的名称叫做RiseNumberTextView,我们在平时使用支付宝的时候会发现进入资产页面的时候,资产数据会从一个数一直不停的增长直至你的真实数据然后停止。


那么这个效果是如何做到的呢?首先来看一下我们做出的效果图,然后我们一起来实现它。




这里面会用到一个核心的类:ValueAnimatr这是一个android属性动画


按照面向接口编程的好习惯,首先定义一个接口:

/** * 增长的数字接口 *  */public interface IRiseNumber {/** * 开始播放动画的方法 */public void start();/** * 设置小数 *  * @param number * @return */public void withNumber(float number);/** * 设置整数 *  * @param number * @return */public void withNumber(int number);/** * 设置动画播放时长 *  * @param duration * @return */public void setDuration(long duration);/** * 设置动画结束监听器 *  * @param callback */public void setOnEndListener(RiseNumberTextView.EndListener callback);}


然后自定义view------数字增长TextView,内容如下:

import android.content.Context;import android.util.AttributeSet;import android.widget.TextView;import com.bear.risenumber.R;import com.nineoldandroids.animation.ValueAnimator;import java.text.DecimalFormat;/** * 自定义RiseNumberTextView继承TextView,并实现接口RiseNumberBase *  */public class RiseNumberTextView extends TextView implements IRiseNumber {private static final int STOPPED = 0;private static final int RUNNING = 1;private int mPlayingState = STOPPED;private float number;private float fromNumber;/** * 动画播放时长 */private long duration = 1500;/** * 1.int 2.float */private int numberType = 2;private DecimalFormat fnum;private EndListener mEndListener = null;final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,99999999, 999999999, Integer.MAX_VALUE };/** * 构造方法 *  * @param context */public RiseNumberTextView(Context context) {super(context);}/** * 使用xml布局文件默认的被调用的构造方法 *  * @param context * @param attr */public RiseNumberTextView(Context context, AttributeSet attr) {super(context, attr);setTextColor(context.getResources().getColor(R.color.rise_number_text_color_red));setTextSize(30);}public RiseNumberTextView(Context context, AttributeSet attr, int defStyle) {super(context, attr, defStyle);}/** * 判断动画是否正在播放 *  * @return */public boolean isRunning() {return (mPlayingState == RUNNING);}/** * 跑小数动画 */private void runFloat() {ValueAnimator valueAnimator = ValueAnimator.ofFloat(fromNumber, number);valueAnimator.setDuration(duration);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {setText(fnum.format(Float.parseFloat(valueAnimator.getAnimatedValue().toString())));if (valueAnimator.getAnimatedFraction() >= 1) {mPlayingState = STOPPED;if (mEndListener != null)mEndListener.onEndFinish();}}});valueAnimator.start();}/** * 跑整数动画 */private void runInt() {ValueAnimator valueAnimator = ValueAnimator.ofInt((int) fromNumber,(int) number);valueAnimator.setDuration(duration);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {//设置瞬时的数据值到界面上setText(valueAnimator.getAnimatedValue().toString());if (valueAnimator.getAnimatedFraction() >= 1) {//设置状态为停止mPlayingState = STOPPED;if (mEndListener != null)//通知监听器,动画结束事件mEndListener.onEndFinish();}}});valueAnimator.start();}static int sizeOfInt(int x) {for (int i = 0;; i++){if (x <= sizeTable[i])return i + 1;}}@Overrideprotected void onFinishInflate() {super.onFinishInflate();fnum = new DecimalFormat("##0.00");}/** * 开始播放动画 */@Overridepublic void start() {if (!isRunning()) {mPlayingState = RUNNING;if (numberType == 1)runInt();elserunFloat();}}/** * 设置一个小数进来 */@Overridepublic void withNumber(float number) {this.number = number;numberType = 2;if (number > 1000) {fromNumber = number- (float) Math.pow(10, sizeOfInt((int) number) - 1);} else {fromNumber = number / 2;}}/** * 设置一个整数进来 */@Overridepublic void withNumber(int number) {this.number = number;numberType = 1;if (number > 1000) {fromNumber = number- (float) Math.pow(10, sizeOfInt((int) number) - 2);} else {fromNumber = number / 2;}}/** * 设置动画播放时间 */@Overridepublic void setDuration(long duration) {this.duration = duration;}/** * 设置动画结束监听器 */@Overridepublic void setOnEndListener(EndListener callback) {mEndListener = callback;}/** * 定义动画结束接口 *  *  */public interface EndListener {/** * 当动画播放结束时的回调方法 */public void onEndFinish();}}

然后在Activity中去使用自定义的view:

import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import com.bear.risenumber.views.RiseNumberTextView;import com.bear.risenumber.views.RiseNumberTextView.EndListener;public class MainActivity extends Activity {private RiseNumberTextView rnTextView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);setupViews();}private void setupViews() {// 获取到RiseNumberTextView对象rnTextView = (RiseNumberTextView) findViewById(R.id.risenumber_textview);// 设置数据rnTextView.withNumber(2666.50f);// 设置动画播放时间rnTextView.setDuration(5000);// 监听动画播放结束rnTextView.setOnEndListener(new EndListener() {@Overridepublic void onEndFinish() {Toast.makeText(MainActivity.this, "数据增长完毕...",Toast.LENGTH_SHORT).show();}});Button btn = (Button) findViewById(R.id.button1);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(rnTextView.isRunning()){Toast.makeText(MainActivity.this, "数字还没增长完,请稍候尝试...", Toast.LENGTH_SHORT).show();}else{// 开始播放动画rnTextView.start();}}});}}


附上示例源码,有兴趣的可以下载导入到Eclipse中去运行以下:

Android Rise Number TextView


更多相关文章

  1. 如何在5.0上实现button的Ripple(水波效果)
  2. Android(安卓)带清除功能的输入框控件EditTextWithDel
  3. Android(安卓)补间动画之平移动画TranslateAnimation
  4. 如何实现Android应用的启动画面(闪屏)?
  5. android viewPager滑动速度设置
  6. Android(安卓)Gradle配置资源前缀
  7. android 利用 MediaPlayer 类播放音乐
  8. Android(安卓)Activity process(进程设置)
  9. android imageview围绕中心旋转动画

随机推荐

  1. Android支持库概述
  2. Android四大组件之服务(service)
  3. android 性能之内存浅析
  4. Android学习历程12-Android(安卓)网络请
  5. 130292015053+李徐恬+第1章作业
  6. Android(安卓)反射获取内外置存储卡方法
  7. android系统编译流程简要分析与使用
  8. Android(安卓)系统分析
  9. adb shell 命令详解
  10. Android(安卓)NDK 第一个例子 HelloNDK