您的位置:首页 > 移动开发 > Android开发

安卓滚动数字的实现(从0开始增加到指定数字)

2016-01-12 14:32 543 查看
核心思想就是在自定义View中重写Animation中的applyTransformation方法,在其中使用postInvalidate()方法刷新界面,调用onDraw()来实现数字变化。

以下是代码与注释:

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;

/**
* 使用内部的Animation驱动View的onDraw使数字滚动
* @author WeiTao
*
*/
public class RuningNumView extends View{

//这里的digit表示的是位数,就是个十百千,因为项目需要所以加上的
private int count, digit;
private String text;
private MyAnimation anim;
private Paint textPaint;
private int textSize;
private RectF frameRectangle = new RectF();

public RuningNumView(Context context) {
super(context);
init();
}

public RuningNumView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public RuningNumView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

public void init(){
text = "0";
anim = new MyAnimation();

final float scale = getContext().getResources().getDisplayMetrics().density;
textSize = (int) (33 * scale + 0.5f);

textPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.LINEAR_TEXT_FLAG);
textPaint.setColor(0xFFFFFFFF);
textPaint.setStyle(Style.FILL_AND_STROKE);
textPaint.setTextSize(textSize);
}

@SuppressLint("DrawAllocation") @Override
protected void onDraw(Canvas canvas){
//处理下要显示出来的数字,这里是为了获得个十百位中的一位
String textStr = (count % (int)Math.pow(10,digit))/(int)Math.pow(10,digit-1) + "";

Rect bounds = new Rect();
textPaint.getTextBounds(textStr, 0, textStr.length(), bounds);

//画出数字
 canvas.drawText(textStr,
frameRectangle.centerX() - (textPaint.measureText(textStr) / 2),
frameRectangle.centerY() + bounds.height() / 2,
textPaint);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int min = Math.min(width, height);
setMeasuredDimension(min, min);

frameRectangle.set(0, 0, min, min);
}

/**
*
* @param text 最终数字
* @param digit 要显示的数位(1/2/3)
*/
public RuningNumView setTextAndDigit(String text, int digit){
this.text = text;
this.digit = digit;
return this;
}

public RuningNumView setDuration(long durationMillis){
anim.setDuration(durationMillis);
return this;
}

public void startAnimation(){
this.startAnimation(anim);
}

public class MyAnimation extends Animation{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if(interpolatedTime < 1.0f){
//随着动画播放,interpolatedTime会由0变化到1,通过它,我们可以获取变化中的数字(乘以下总数就行了)
count = (int)(interpolatedTime * Float.parseFloat(text));
}else{
count = Integer.parseInt(text);
}
postInvalidate();//调用onDraw()
}
}
}


变量设置:

RuningNumView tx_num1, tx_num2, tx_num3;
String score = "750";


以下依次是百位、十位、个位,两秒的动画,同时执行:

tx_num1.setDuration(2000).setTextAndDigit(score, 3);
tx_num2.setDuration(2000).setTextAndDigit(score, 2);
tx_num3.setDuration(2000).setTextAndDigit(score, 1);

tx_num1.startAnimation();
tx_num2.startAnimation();
tx_num3.startAnimation();


这里外部用的是LinearLayout布局:

<com.taotaojin.view.RuningNumView
android:id="@+id/tx_num1"
android:layout_width="45dp"
android:layout_height="55dp"/>

<com.taotaojin.view.RuningNumView
android:id="@+id/tx_num2"
android:layout_width="45dp"
android:layout_height="55dp" />

<com.taotaojin.view.RuningNumView
android:id="@+id/tx_num3"
android:layout_width="45dp"
android:layout_height="55dp"/>


当然,也可以写成一个View就显示完整数字,我把它们拆分开完全是因为项目需要。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android