本人只是一个1年android的小菜鸟,今天公司需要做一个仿余额宝数字跳转的效果,我在网上找了许多demo,发现动画只提供float和
int类型的参数,但是恰恰好公司的金额比较大,int和float都无法满足精度,所以只有自己动手改了。
/**
* Created by Chen on 2015/11/30.
*/
public interface IRunNumber {
public void start ();
public RunNumberTextView withNumber (int number);
public RunNumberTextView setDuration (long duration);
public void setOnEnd (RunNumberTextView.EndListener callback);
}
先写一个接口提供动画完成的监听。
/**
* Created by Chen on 2015/11/30.
*/
public class RunNumberTextView extends TextView implements IRiseNumberBase {
private static final int STOPPED = 0 ;
private static final int RUNNING = 1 ;
private int mPlayingState = STOPPED;
private int number;
private int 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 RunNumberTextView (Context context) {
super (context);
}
public RunNumberTextView (Context context, AttributeSet attr) {
super (context, attr);
}
public RunNumberTextView (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 == 2 )
runInt();
else
runFloat();
}
}
@Override
public RunNumberTextView withNumber (int number) {
this .number = number;
numberType = 2 ;
if (number > 1000 ) {
fromNumber = number - (int ) Math.pow(10 , sizeOfInt((int ) number) - 2 );
} else {
fromNumber = number / 2 ;
}
return this ;
}
public RunNumberTextView withNumber (int number ,int numberType) {
this .number = number;
this .numberType = numberType;
if (number > 1000 ) {
fromNumber = number - (int ) Math.pow(10 , sizeOfInt((int ) number) - 2 );
} else {
fromNumber = number / 2 ;
}
return this ;
}
@Override
public RunNumberTextView setDuration (long duration) {
this .duration = duration;
return this ;
}
@Override
public void setOnEnd (EndListener callback ) {
mEndListener = callback;
}
}
这里我图自己的方便没有写float的跳动方法,如果有需要的话,可以自行添加,这里解决大额金额数字跳转的方法就是添加动画结束后
的监听,RunNumberTextView.senOnEnd(new EndListener()),然后在里面可以直接RunNumberTextView.setText();直接用
一个字符串将你要显示的数字放进去,这样写就是绕过了精度的问题,取了一个巧,希望能帮助和我有同样问题的猿人们。