本案例是使用开源组件RiseNumberTextView来实现类似手机支付宝中增长的数字效果,首先我们来看一下开源组件中的两个类分别如下:
- package com.bear.risenumbertest.lib;
- publicinterface RiseNumberBase {
- publicvoid start();
- public RiseNumberTextView withNumber(float number);
- public RiseNumberTextView withNumber(int number);
- public RiseNumberTextView setDuration(long duration);
- publicvoid setOnEnd(RiseNumberTextView.EndListener callback);
- }
另一个类:
- package com.bear.risenumbertest.lib;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.widget.TextView;
- import com.nineoldandroids.animation.ValueAnimator;
- import java.text.DecimalFormat;
- publicclass RiseNumberTextView extends TextView implements RiseNumberBase{
- privatestaticfinalint STOPPED = 0;
- privatestaticfinalint RUNNING = 1;
- privateint mPlayingState = STOPPED;
- privatefloat number;
- privatefloat fromNumber;
- privatelong duration=1500;
- /**
- * 1.int 2.float
- */
- privateint numberType=2;
- private DecimalFormat fnum;
- private EndListener mEndListener=null;
- finalstaticint[] 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);
- }
- publicinterface EndListener {
- publicvoid onEndFinish();
- }
- publicboolean isRunning() {
- return (mPlayingState == RUNNING);
- }
- privatevoid runFloat(){
- ValueAnimator valueAnimator = ValueAnimator.ofFloat(fromNumber, number);
- valueAnimator.setDuration(duration);
- valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- publicvoid onAnimationUpdate(ValueAnimator valueAnimator) {
- setText(fnum.format(Float.parseFloat(valueAnimator.getAnimatedValue().toString())));
- if (valueAnimator.getAnimatedFraction()>=1){
- mPlayingState = STOPPED;
- if (mEndListener!=null)
- mEndListener.onEndFinish();
- }
- }
- });
- valueAnimator.start();
- }
- privatevoid runInt(){
- ValueAnimator valueAnimator = ValueAnimator.ofInt((int)fromNumber, (int)number);
- valueAnimator.setDuration(duration);
- valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- publicvoid onAnimationUpdate(ValueAnimator valueAnimator) {
- setText(valueAnimator.getAnimatedValue().toString());
- if (valueAnimator.getAnimatedFraction()>=1){
- mPlayingState = STOPPED;
- if (mEndListener!=null)
- mEndListener.onEndFinish();
- }
- }
- });
- valueAnimator.start();
- }
- staticint sizeOfInt(int x) {
- for (int i = 0;; i++)
- if (x <= sizeTable[i])
- return i + 1;
- }
- @Override
- protectedvoid onFinishInflate() {
- super.onFinishInflate();
- fnum= new DecimalFormat("##0.00");
- }
- @Override
- publicvoid start() {
- if (!isRunning()) {
- mPlayingState = RUNNING;
- if (numberType==1)
- runInt();
- else
- runFloat();
- }
- }
- @Override
- public RiseNumberTextView withNumber(float number) {
- this.number=number;
- numberType=2;
- if (number>1000){
- fromNumber=number-(float)Math.pow(10,sizeOfInt((int)number)-2);
- }else {
- fromNumber=number/2;
- }
- returnthis;
- }
- @Override
- public RiseNumberTextView 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;
- }
- returnthis;
- }
- @Override
- public RiseNumberTextView setDuration(long duration) {
- this.duration=duration;
- returnthis;
- }
- @Override
- publicvoid setOnEnd(EndListener callback) {
- mEndListener=callback;
- }
- }
将这两个类集成到我们的工程中后,就可以使用了,下面这个是使用范例:
[java] view plain copy
- package com.bear.risenumbertest;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.widget.Toast;
- import com.bear.risenumbertest.lib.RiseNumberTextView;
- import com.bear.risenumbertest.lib.RiseNumberTextView.EndListener;
- publicclass MainActivity extends Activity {
- @Override
- protectedvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //获取到RiseNumberTextView对象
- RiseNumberTextView rnTextView = (RiseNumberTextView) findViewById(R.id.risenumber_textview);
- // 设置数据
- rnTextView.withNumber(2666.50f);
- // 设置动画播放时间
- rnTextView.setDuration(5000);
- // 开始播放动画
- rnTextView.start();
- // 监听动画播放结束
- rnTextView.setOnEnd(new EndListener() {
- @Override
- publicvoid onEndFinish() {
- Toast.makeText(MainActivity.this, "数据增长完毕...",
- Toast.LENGTH_SHORT).show();
- }
- });
- }
- @Override
- publicboolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- returntrue;
- }
- }
附上效果图:
最后附上完整的工程源码链接:
android之增长的数字动画
良心的公众号,更多精品文章,不要忘记关注哈
《Android和Java技术栈》