某些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. NLP︱高级词向量表达(一)——GloVe(理论、相关测评结果、R&python实现、相关应用)

    有很多改进版的word2vec,但是目前还是word2vec最流行,但是Glove也有很多在提及,笔者在自己实验的时候,发现Glove也还是有很多优点以及可以深入研究对比的地方的,所以对其进行了一定的 ...

  2. Linux系统挂载NTFS文件系统

     今天尝试并成功的将一块500G的移动硬盘挂载到了RHEL5的系统上,甚感欣慰.想到也许以后自己或其他同学们会有类似经历,于是尽量细致的记录于此.     无论是一块安装了Windows/Linu ...

  3. dependencies 与 devDependencies 的区别

    dependencies 与 devDependencies 的区别 在使用 npm install 安装 npm 包时,有两种命令参数可以把它们的信息写入 package.json 文件: --sa ...

  4. halcon c++ 异常处理

    现象 Halcon导出的C++程序,try catch不到异常.在Halcon下可以正常Catch到异常.  C++代码:try{   tuple_max(hv_Length, &hv_Max ...

  5. jquery的动画学习--jquery权威指南

        前面的fadeIn和fadeOut还有fadeTo以及sildeToggle还有sildeUp\sildeDown还有toggle还有show.hide等都经常用,就不再手写了,需要注意的是f ...

  6. 【BZOJ1412】狼和羊的故事(网络流)

    [BZOJ1412]狼和羊的故事(网络流) 题面 Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听 ...

  7. 清除input[type=number]的默认样式

    input[type=number] { -moz-appearance:textfield; } input[type=number]::-webkit-inner-spin-button, inp ...

  8. Gradle下载 Jar 包

    使用此方法下载Jar包的前提是已经配置好了Gradle的环境了,配置好的标志是在终端输入gradle不提示command not found. 1. 编写build.gradle文件代码: apply ...

  9. java中数组复制的两种方式

    在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...

  10. javascript DOM操作 节点的遍历

    通过javascript的遍历可以由一个节点来查找它的子节点(childNodes).兄弟节点(nextSibling/previousSibling)和父节点(parentNode). 代码说明: ...