作为一个出水不忘挖井人的小码仔,今天算是第一次正式发表博客,不求文章质量怎么样,但求能帮到有需要的人。
目前许多游戏中的一些参数,如分数、金币数在变化的时候都是数字蹭蹭蹭的往上涨,不断变化。今天我就分享一下我通过参考别人再自己做过改良的自定义控件。
废话不说,先上代码:
控件:
public class NumberTextView extends TextView implements IRiseNumber{
private static final int STOPPED = 0;
private static final int RUNNING = 1;
private int mPlayingState = STOPPED;
private float number;
private float fromNumber;
private int textColor; // 数字的颜色
private int textSize; // 数字的字号
/**
* 默认时长
*/
private long duration = 1000;
/**
* 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};
/**
* 构造方法
*
* @param context
*/
public NumberTextView(Context context) {
super(context);
}
/**
* 构造方法
*
* @param context
* @param attr
*/
public NumberTextView(Context context, AttributeSet attr) {
super(context, attr);
TypedArray array = context.obtainStyledAttributes(attr, R.styleable.NumberTextView);
if(array != null){
textColor = array.getColor(R.styleable.NumberTextView_numberColor, Color.BLACK);
textSize = array.getInt(R.styleable.NumberTextView_numberSize, 20);
}
setTextColor(textColor);
setTextSize(textSize);
}
public NumberTextView(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
TypedArray array = context.obtainStyledAttributes(attr, R.styleable.NumberTextView);
if(array != null){
textColor = array.getColor(R.styleable.NumberTextView_numberColor, Color.BLACK);
textSize = array.getInt(R.styleable.NumberTextView_numberSize, 20);
}
setTextColor(textColor);
setTextSize(textSize);
}
/**
* 动画是否正在执行
*
* @return
*/
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=i+10) {
if (x <= sizeTable[i])
return i + 10;
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
fnum = new DecimalFormat("##0");
}
/**
* 开始动画
*/
@Override
public void start() {
if (!isRunning()) {
mPlayingState = RUNNING;
if (numberType == 1)
runInt();
else
runFloat();
}
}
/**
* 设置数字(整数型)
* @param number
*/
@Override
public void 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;
}
}
/**
* 设置数字(浮点型)
* @param number
*/
@Override
public void withNumber(float number) {
this.number = number;
numberType = 2;
if (number > 1000) {
fromNumber = number
- (float) Math.pow(10, sizeOfInt((int) number) - 1);
} else {
fromNumber = number / 2;
}
}
/**
* 设置 开始 和 结束 数字(整数型)
* @param fromNumber
* @param endNumber
*/
@Override
public void setFromAndEndNumber(int fromNumber, int endNumber) {
this.fromNumber = fromNumber;
this.number = endNumber;
numberType = 1;
}
/**
* 设置 开始 和 结束 数字(浮点型)
* @param fromNumber
* @param endNumber
*/
@Override
public void setFromAndEndNumber(float fromNumber, float endNumber) {
this.fromNumber = fromNumber;
this.number = endNumber;
numberType = 2;
}
/**
* 设置动画时长
*/
@Override
public void setDuration(long duration) {
this.duration = duration;
}
/**
* 设置动画结束监听
*/
@Override
public void setOnEndListener(EndListener callback) {
mEndListener = callback;
}
/**
* 动画结束接口
*/
public interface EndListener {
/**
* 动画结束
*/
public void onEndFinish();
}
}
看起来不少,其实方法就那几个。
至于用到的接口就在这里
接口类:
public interface IRiseNumber {
public void start();
public void withNumber(int number);
public void withNumber(float number);
public void setFromAndEndNumber(int startNum, int EndNum);
public void setFromAndEndNumber(float startNum, float EndNum);
public void setDuration(long time);
public void setOnEndListener(NumberTextView.EndListener listener);
}
控件中有两个自定义属性,这个需要你在res/values/attrs中添加
attrs.xml
<declare-styleable name="NumberTextView">
<attr name="numberColor" format="color|reference"/>
<attr name="numberSize" format="integer|reference"/>
</declare-styleable>
于是在布局中
xml布局:
<com.test.myView.NumberTextView
android:id="@+id/tv_numberToAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
app:numberColor="@color/colorBlue"
app:numberSize="30" />
最后就是在代码中调用了
private NumberTextView tv_addNumber;
public void addNumberClick(View view) {
tv_addNumber.setFromAndEndNumber(0, 100); //设置开始和结束的数字,支持整数型和浮点型
//
tv_addNumber.setDuration(1500); //设置动画时间
tv_addNumber.start(); //开始动画
}
调用start()方法,就可以看到数字蹭蹭蹭的涨了。
就到这里吧,希望对大家有哪怕一丢丢帮助。