一:想都不用想的,有图有真相,看着爽了,在看下面源码
二:实例源码分析
①:首先定义接口
package com.demo.tools.view; /** * 数字动画自定义 * * @author zengtao 2015年7月17日 上午11:48:27 * */ public interface RiseNumberBase { public void start(); public RiseNumberTextView withNumber(float number); public RiseNumberTextView withNumber(float number, boolean flag); public RiseNumberTextView withNumber(int number); public RiseNumberTextView setDuration(long duration); public void setOnEnd(RiseNumberTextView.EndListener callback); }
②:自定义控件
package com.demo.tools.view; import android.animation.ValueAnimator; import android.content.Context; import android.util.AttributeSet; import android.widget.TextView; import com.demo.tools.Utils; /** * 数字动画自定义 * * @author zengtao 2015年7月17日 上午11:48:03 * */ public class RiseNumberTextView extends TextView implements RiseNumberBase { 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 = 1000; /** * 1.int 2.float */ private int numberType = 2; private boolean flags = true; private EndListener mEndListener = null; final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; public RiseNumberTextView(Context context) { super(context); } public RiseNumberTextView(Context context, AttributeSet attr) { super(context, attr); } public RiseNumberTextView(Context context, AttributeSet attr, int defStyle) { super(context, attr, defStyle); } public interface EndListener { public void onEndFinish(); } public boolean isRunning() { return (mPlayingState == RUNNING); } private void runFloat() { ValueAnimator valueAnimator = ValueAnimator.ofFloat(fromNumber, number); valueAnimator.setDuration(duration); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { if (flags) { setText(Utils.format(",##0.00").format(Double.parseDouble(valueAnimator.getAnimatedValue().toString())) + ""); if (valueAnimator.getAnimatedValue().toString().equalsIgnoreCase(number + "")) { setText(Utils.format(",##0.00").format(Double.parseDouble(number + ""))); } } else { setText(Utils.format("##0.00").format(Double.parseDouble(valueAnimator.getAnimatedValue().toString())) + ""); if (valueAnimator.getAnimatedValue().toString().equalsIgnoreCase(number + "")) { setText(Utils.format("##0.00").format(Double.parseDouble(number + ""))); } } 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() { @Override public 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; } @Override protected void onFinishInflate() { super.onFinishInflate(); } @Override public void start() { if (!isRunning()) { mPlayingState = RUNNING; if (numberType == 1) runInt(); else runFloat(); } } @Override public RiseNumberTextView withNumber(float number, boolean flag) { this.number = number; this.flags = flag; numberType = 2; fromNumber = 0; return this; } @Override public RiseNumberTextView withNumber(float number) { System.out.println(number); this.number = number; numberType = 2; fromNumber = 0; return this; } @Override public RiseNumberTextView withNumber(int number) { this.number = number; numberType = 1; fromNumber = 0; return this; } @Override public RiseNumberTextView setDuration(long duration) { this.duration = duration; return this; } @Override public void setOnEnd(EndListener callback) { mEndListener = callback; } }
③工具类的编写
package com.demo.tools; import java.math.RoundingMode; import java.text.DecimalFormat; /** * 配置文件 * @author zengtao 2015年7月17日 上午11:47:44 * */ public class Utils { /** * 格式化 */ private static DecimalFormat dfs = null; public static DecimalFormat format(String pattern) { if (dfs == null) { dfs = new DecimalFormat(); } dfs.setRoundingMode(RoundingMode.FLOOR); dfs.applyPattern(pattern); return dfs; } }
三:主界面调用
package com.demo.ui; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import com.demo.tools.view.RiseNumberTextView; /** * 数字动画 * * @author zengtao 2015年7月17日 上午11:48:54 * */ public class MainActivity extends Activity { private RiseNumberTextView number1, number2, number3, number4, number5; private Button start; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); initView(); } private void initView() { number1 = (RiseNumberTextView) findViewById(R.id.number1); number2 = (RiseNumberTextView) findViewById(R.id.number2); number3 = (RiseNumberTextView) findViewById(R.id.number3); number4 = (RiseNumberTextView) findViewById(R.id.number4); number5 = (RiseNumberTextView) findViewById(R.id.number5); start = (Button) findViewById(R.id.start); start.setOnClickListener(listener); } OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { if (v == start) { initData(); } } }; private void initData() { number1.withNumber(12.3f).start(); number2.withNumber(16.3f).start(); number3.withNumber(10.3f).start(); number4.withNumber(18.3f).start(); number5.withNumber(17.3f).start(); } }