效果图: 点击start将会从初始值 到结束值 以滚动的形式进行轮滚。
1.创建思想:
首先我们可以确定的是动画,这是一个动画,我们可以选择通过属性动画来进行实现;
然后对这些数字进行约束,进行格式化,我会一步一步讲解实现步骤,
2.实现过程:
1) 首先这是一个文本,所以我们要自定义一个文本,ScrollingDigitalAnimation 继承 TextView
2) 判断设置的数字合法性
if (checkNumString(numberStart, numberEnd)) {
// 数字合法 开始数字动画 start(); } else { //数字不合法 直接调用 setText 设置最终值 setText(prefixString + numberEnd + postfixString); }
通过代码可以知道,如果数字合法,直接开启动画,如果数字不合法,通过将数字字符串进行拆分显示,
3) 判断数字的合法性
try { new BigInteger(numberStart);
new BigInteger(numberEnd);
isInt = true;
} catch (Exception e) {
isInt = false;
e.printStackTrace();
}
try {
BigDecimal start = new BigDecimal(numberStart); // 起始数字小数的筛选
BigDecimal end = new BigDecimal(numberEnd); // 最终数字小数的筛选
return end.compareTo(start) >= 0; // 比较小数是否大于等于0
} catch (Exception e) {
e.printStackTrace();
return false;
}
4) 最后一步进行动画的设置(废话少说直接上代码)
// 创建数字动画 并设置起始值和最终值ValueAnimator animator = ValueAnimator.ofObject(new BigDecimalEvaluator(), new BigDecimal(numStart),
new BigDecimal(numEnd)
);
//设置动画持续的时间
animator.setDuration(duiation);
//设置动画内插器
animator.setInterpolator(new AccelerateDecelerateInterpolator());
//动画监听器
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
BigDecimal value = (BigDecimal) animation.getAnimatedValue();
//设置显示的数值
setText(prefixString + format(value) + postfixString);
}
});
animator.start(); //启动动画
通过设置动画来完成本次的效果。这里讲解的是大概流程,为大家梳理大致的流程,
5) 全部代码展示 (ScrollingDigitalAnimation 类)
/** * Created by Administrator on 2019/7/30 0030.
* 功能简介:跳动的数字
*/
public class ScrollingDigitalAnimation extends TextView {
private String numStart = "0"; // 起始值
private String numEnd; // 结束值
private long duiation = 2000; // 持续时间
private String prefixString = ""; // 前缀字符串
private String postfixString = ""; // 后缀字符串
private boolean isInt; // 是否是整数
public ScrollingDigitalAnimation(Context context) {
super(context);
}
public ScrollingDigitalAnimation(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ScrollingDigitalAnimation(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setNumberString(String number) {
setNumberString("0", number);
}
public void setNumberString(String numberStart, String numberEnd) {
numStart = numberStart; // 得到设置的起始数字
numEnd = numberEnd; // 得到设置的最终数字
if (checkNumString(numberStart, numberEnd)) {
// 数字合法 开始数字动画
start();
} else {
//数字不合法 直接调用 setText 设置最终值
setText(prefixString + numberEnd + postfixString);
}
}
/**
* 设置前字符串符号方法
*/
public void setPrefixString(String prefixString) {
this.prefixString = prefixString;
}
/**
* 设置后字符串符号方法
*/
public void setPostfixString(String postfixString) {
this.postfixString = postfixString;
}
/**
* 校验数字合法性
* <p>
* numberStart 开始的数字
* numberEnd 开始的数字
*
* @return 合法性
*/
private boolean checkNumString(String numberStart, String numberEnd) {
try {
new BigInteger(numberStart);
new BigInteger(numberEnd);
isInt = true;
} catch (Exception e) {
isInt = false;
e.printStackTrace();
}
try {
BigDecimal start = new BigDecimal(numberStart); // 起始数字小数的筛选
BigDecimal end = new BigDecimal(numberEnd); // 最终数字小数的筛选
return end.compareTo(start) >= 0; // 比较小数是否大于等于0
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 设置动画
*/
private void start() {
// 创建数字动画 并设置起始值和最终值
ValueAnimator animator = ValueAnimator.ofObject(new BigDecimalEvaluator(), new BigDecimal(numStart),
new BigDecimal(numEnd)
);
//设置动画持续的时间
animator.setDuration(duiation);
//设置动画内插器
animator.setInterpolator(new AccelerateDecelerateInterpolator());
//动画监听器
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
BigDecimal value = (BigDecimal) animation.getAnimatedValue();
//设置显示的数值
setText(prefixString + format(value) + postfixString);
}
});
animator.start(); //启动动画
}
/**
* 格式化 BigDecimal, 小数部分时保留两位小数并四舍五入
* */
private String format(BigDecimal bd){
String pattern;
if(isInt){ // 如果是整数
pattern = "#,###"; // 整数格式
}else{
pattern = "#,##0.00"; //小数格式
}
DecimalFormat df = new DecimalFormat(pattern); //进行格式化
return df.format(bd); //返回格式化后的字符串
}
/**
* 计算线性内插的结果
* */
static class BigDecimalEvaluator implements TypeEvaluator {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
BigDecimal start = (BigDecimal) startValue;
BigDecimal end = (BigDecimal) endValue;
BigDecimal result = end.subtract(start);
return result.multiply(new BigDecimal(""+fraction)).add(start);
}
}
}
6) 使用
/** * 设置金钱的动画
* */
money.setPrefixString("¥");
money.setNumberString("9","999999999"); //设置起始于结束的数字
/**
* 设置动画效果
* */
number.setNumberString("1234567890");
/**
* 设置百分比
* */
percentage.setPostfixString("%");
percentage.setNumberString("0.99","99.99");