Android之增长的数字

来源:互联网 发布:淘宝淘金币怎么用 编辑:程序博客网 时间:2024/05/18 03:58

本案例是使用开源组件RiseNumberTextView来实现类似手机支付宝中增长的数字效果,首先我们来看一下开源组件中的两个类分别如下:

package com.bear.risenumbertest.lib;public interface RiseNumberBase {    public void start();    public RiseNumberTextView withNumber(float number);    public RiseNumberTextView withNumber(int number);    public RiseNumberTextView setDuration(long duration);    public void 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;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=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 };    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) {                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() {            @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();        fnum=   new DecimalFormat("##0.00");    }    @Override    public void 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;        }        return this;    }    @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;        }        return this;    }    @Override    public RiseNumberTextView setDuration(long duration) {        this.duration=duration;        return this;    }    @Override    public void setOnEnd(EndListener callback) {        mEndListener=callback;    }}

将这两个类集成到我们的工程中后,就可以使用了,下面这个是使用范例:

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;public class MainActivity extends Activity {@Overrideprotected void 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() {@Overridepublic void onEndFinish() {Toast.makeText(MainActivity.this, "数据增长完毕...",Toast.LENGTH_SHORT).show();}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}

附上效果图:



最后附上完整的工程源码链接:

android之增长的数字动画

2 0