某些app上,新进入一个Activity的时候,上面的一个关键性数字(比如金额)会以一个数字不断变大的动画来显示。刚开始的时候,想到的一个方案是:使用Thead+Handler,给定一个动画总时长与刷新间隔时长,根据公式(数字从0开始,每次增长值为数组除以动画执行次数,动画执行次数等于动画总时长除以刷新间隔时长);

每隔一段时间重新设置TextView的字符串为增加后的值,直到动画结束显示最终结果。
其实对安卓动画有一定了解的应该都知道ValueAnimator这个类,我们可以使用它来很好的实现所要的效果,而不需要我们自己来生硬的控制隔多久就增加多少刷新显示。根据ValueAnimator的属性方法以及实际需要,我们封装一个自定义View来实现我们的需求。

先看一下我实现的效果图

接下来上关键代码:

自定义View,其实就是继承一个TextView,代码实现很简单,代码中也有注释

/**
* Created by dingchao on 2018/3/27.
*/ public class DcTextViewRunNumber extends TextView { /**
* 延迟
*/
private final int DELAY = 20;
/**
* 保留小数位数 默认2为
*/
private final int DECIMALS_COUNT = 2;
private final int START_RUN = 101;
private final int STOP_RUN = 102;
/**
* 跑的次数
*/
private final int RUN_COUNT = 40;
private float speed;
private float startNum;
private float endNum;
/**
* 保留小数位数
*/
private int decimals = DECIMALS_COUNT;
/**
* 每次跑的次数
*/
private int runCount = RUN_COUNT;
/**
* 动画延迟
*/
private int delayMillis = DELAY;
private boolean isAniming; private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == START_RUN) {
if(speed==0){
if(endNum!=0){
speed = getSpeed();
startNum = speed;
}else{
return ;
}
}
isAniming = !running();
if (isAniming) {
sendEmptyMessageDelayed(START_RUN, delayMillis);
}else{
speed = 0;
startNum = 0;
}
}
};
}; public DcTextViewRunNumber(Context context) {
super(context);
} public DcTextViewRunNumber(Context context, AttributeSet attrs) {
super(context, attrs);
} public DcTextViewRunNumber(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} /**
* 开始数字跳动动画
* @return 动画是否结束
*/
private boolean running() {
setText(withDEC(String.valueOf(startNum)) + "");
startNum +=speed;
if(startNum >= endNum){
setText(withDEC(String.valueOf(endNum)) + "");
return true;
}
return false;
} /**
* 计算速度
* @return
*/
private float getSpeed(){
float speedFloat = withDEC(String.valueOf(endNum/runCount)).floatValue();
return speedFloat;
} /**
* 判断是否是非负数
* @return
*/
private boolean isNumber(String num){
if("".equals(num) || num==null)
return false;
Pattern pattern = Pattern.compile("^\\d+$|\\d+\\.\\d+$");
Matcher matcher = pattern.matcher(num);
return matcher.find();
} /**
* 取整四舍五入 保留小数
* @param num
* @return
*/
private BigDecimal withDEC(String num){
return new BigDecimal(num).setScale(decimals, BigDecimal.ROUND_HALF_UP);
} /**
* 设置显示的数字
* @param num
*/
public void setShowNum(String num){
setShowNum(num,DECIMALS_COUNT);
} /**
* 设置显示的数字
* @param num
* @param decimals 要保留的小数位
*/
public void setShowNum(String num,int decimals){
if(!isNumber(num)){
return;
}
setText(num);
setDecimals(decimals);
} /**
* 开始跑
*/
public void startRun(){
if(isAniming){
return ;
}
if(isNumber(getText().toString())){
endNum = withDEC(getText().toString()).floatValue();
mHandler.sendEmptyMessage(START_RUN);
}
} public int getDecimals() {
return decimals;
} /**
* 设置保留的小数位 0:不保留小数
* @param decimals
*/
public void setDecimals(int decimals) {
if(decimals>=0){
this.decimals = decimals;
}
setText(withDEC(getText().toString())+"");
} public int getRunCount() {
return runCount;
} /**
* 设置动画跑的次数
* @param runCount
*/
public void setRunCount(int runCount) {
if(runCount<=0){
return ;
}
this.runCount = runCount;
} public int getDelayMillis() {
return delayMillis;
} /**
* 设置动画延迟
* @param delayMillis
*/
public void setDelayMillis(int delayMillis) {
this.delayMillis = delayMillis;
}

接下来看怎么使用,MainActivity.java中

public class MainActivity extends AppCompatActivity {
private DcTextViewRunNumber numberRunView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); numberRunView = (DcTextViewRunNumber) findViewById(R.id.numberRunView);
numberRunView.setShowNum("711", 0);//终止的数字,小数点,这里为0所以没有小数点
numberRunView.setRunCount(50);//动画执行的次数,50次执行完
// numberRunView.setShowNum("221.918899");
numberRunView.startRun();//
} /**
* @param view
*/
public void runClick(View view) {
numberRunView.startRun();
} }

activity_main.xml也贴一下吧,贴全了吧

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity"> <cn.up.com.textviewrun.DcTextViewRunNumber
android:id="@+id/numberRunView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="123"
android:textSize="30sp" /> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="runClick"
android:text="跑" /> </LinearLayout>

主要的就是这三个文件,代码都全部贴出来了,效果也还可以。开发中不要重复造轮子,有的改一下就可以直接用咯。

Android TextView数字增长动画效果的更多相关文章

  1. android中设置Animation 动画效果

    在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...

  2. Android Acitivy切换平移动画效果实现

    1.在anim目录下新建anim文件夹,新建tran_in.xml和tran_out.xml分别表示下一页切换进入,和本页切换出去. 即in表示下一页向左平移,out表示同样向左平移至消失. tran ...

  3. android标题栏下面弹出提示框(一) TextView实现,带动画效果

    产品经理用的是ios手机,于是android就走上了模仿的道路.做这个东西也走了一些弯路,写一篇博客放在这里,以后自己也可用参考,也方便别人学习. 弯路: 1.刚开始本来用PopupWindow去实现 ...

  4. Android实现控件动画效果

    MainActivity.java public class MainActivity extends AppCompatActivity { private ImageView iv; privat ...

  5. 【转】Android 实现蘑菇街购物车动画效果

    原文出处:http://blog.csdn.net/wangjinyu501/article/details/38400479 1.思路   目前想到两种方式实现这种效果,一是使用Tween动画,直截 ...

  6. Android 实现蘑菇街购物车动画效果

    版本号:1.0  日期:2014.8.6 版权:© 2014 kince 转载注明出处   使用过蘑菇街的用户基本上都知道有一个增加购物车的动画效果,此处不详细描写叙述想知道的能够去下载体验一下. 1 ...

  7. Android开发之View动画效果插补器Interpolator

    插补器Interpolator 官网描述:An interpolator defines the rate of change of an animation. This allows the bas ...

  8. Android 之Activity切换动画效果

    在Activity中Android提供了overridePendingTransition(int enterAnim,int exitAnim)这个方法用于设置Activity之间切换的动画效果.o ...

  9. Android 为PopupWindow设置动画效果

    首先定义显示效果的动画文件: <?xml version="1.0" encoding="utf-8"?> <set xmlns:androi ...

随机推荐

  1. 【转载】使用SDL播放YUV图像数据(转)

    SDL提供了针对YUV格式数据的直接写屏操作.废话不多说,直接上代码吧/** * file showyuv.c * author: rare * date: 2009/12/06 * email: d ...

  2. Android学习基础之onSaveInstanceState和onRestoreInstanceState触发的时机

    先看Application Fundamentals上的一段话:    Android calls onSaveInstanceState() before the activity becomes ...

  3. freemarker报错之十二

    1.错误描述 六月 04, 2014 10:31:47 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Template proc ...

  4. VxWorks操作系统shell命令与调试方法总结

    VxWorks下的调试手段 主要介绍在Tornado集成开发环境下的调试方法,和利用支撑定位问题的步骤.思路. 1         Tornado的调试工具 嵌入式实时操作系统VxWorks和集成开发 ...

  5. web开发性能优化---UI界面篇

    1.尽量采用div+css布局 DIV+CSS相比较与表格布局的优势: a.代码精简 使用DIV+CSS布局,页面代码精简,这一点对XHTML有所了解的都知道.代码精简所带来的直接好处有两点:一是提高 ...

  6. Unity开发之存档和读档的三种实现方式

    此文内容源自siki学院视频,仅供学习!视频链接地址:http://www.sikiedu.com/course/129 工程使用Unity 2017.3.0f3 (64-bit) 老司机读博客,了解 ...

  7. Array.from()

    es6 Array.from() 方法将两类对象转为真正的数组 用法:用于将两类对象转为真正的数组:类似数组的对象和可遍历(iterable)的对象(包含ES6新增的数据结构Set和Map); 说明: ...

  8. history对象的使用--JavaScript基础

    history对象提供与历史清单有关的信息,包含最经访问过的10个网页的URL 1.history对象常用属性 length 返回浏览器历史列表中URL数量 <!DOCTYPE html> ...

  9. Rolling Update - 每天5分钟玩转 Docker 容器技术(140)

    滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 下面我们部署三副本应用,初始镜 ...

  10. 【BZOJ1834】网络扩容(最大流,费用流)

    [BZOJ1834]网络扩容(最大流,费用流) 题面 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下 ...