专栏名称: 郭霖
Android技术分享平台,每天都有优质技术文章推送。你还可以向公众号投稿,将自己总结的技术心得分享给大家。
目录
相关文章推荐
stormzhang  ·  来自李子柒的压迫感 ·  17 小时前  
鸿洋  ·  理解Android ... ·  昨天  
鸿洋  ·  Android H5页面性能分析策略 ·  3 天前  
鸿洋  ·  AndroidManifest中uses-l ... ·  1 周前  
51好读  ›  专栏  ›  郭霖

教你如何自定义数字会滚动的TextView

郭霖  · 公众号  · android  · 2017-05-25 08:00

正文

今日科技快讯

近日,2017最新福布斯全球品牌榜公布了:排名第一的苹果公司品牌价值高达1700亿美元;第二是搜索巨头谷歌,其品牌价值为1018亿美元;前五名中还包括微软(870亿美元)、Facebook(735亿美元)和可口可乐(564亿美元)。五强中,前四家都是科技或互联网公司,可见这些科技公司对于人类生活和商业活动的巨大影响力。

作者简介

本篇是 Chay_Chan 的第四篇投稿,分享了自己的一个开源控件,效果不错,希望大家喜欢。

Chay_Chan 的博客地址:

http://blog.csdn.net/chay_chan

介绍

NumberRunningTextView 是一个自带数字滚动动画的 TextView,通过使用 setContent(String str)方法,传入相应的金额数字字符串(如”1354.00”),或者数字的字符串(如200),当页面初始化完成的时候,就可以看到数字滚动的效果,和支付宝中进入余额宝界面,显示余额滚动的效果类似,具体的效果如下:

使用

在布局文件中,使用 NumberRunningTextView,代码如下:

演示金额滚动的 NumberRunningTextView

演示整数数字滚动的 NumberRunningTextView

二者的区别在于 textType 的设置,textType 是用于指定内容的格式,总共有 money(金钱格式,带小数) 和 num(整数格式),默认是金钱的格式,不配置 textType 的话,默认就是使用金钱格式。

在Java文件中根据 id 找到对应的 view 后,调用 setContent()方法 即可。

tvMoney.setContent("1354.00");
tvNum.setContent("200");

关闭金额的自动格式化(每三位数字添加一个逗号)

上图所示,最后显示的金额数字经过了处理,每三位添加一个逗号,这使得数字看起来比较好看,金额默认是使用这种格式,如果不想要这种格式的数字,可以在布局文件中,NumberRunningTextView 的配置中,将 useCommaFormat 设置为 false,这样最终的数字就不会是带有逗号了,效果如下:

关闭执行动画的时机

当一开始进入界面的时候,初始化数据完毕,NumberRunningTextView 设置数据完毕,会自动执行数字滚动的动画,如果进行刷新操作,从服务器获取新的数据,重新设置数据,NumberRunningTextView 会自动判断传入的内容是否有变化,如果没有变化,则不会再次滚动,这和支付宝的余额宝界面中的金额类似,当在余额宝界面下拉刷新时,金额没有变化,数字不会再次滚动,而当提现后重新回到该界面,金额发生变化后,就会再次滚动,效果如下:

SwipeRefreshLayout 的刷新回调中,只做了这样的处理,NumberRunningTextView 设置的内容还是原来的数据。

当你进行下拉刷新的时候,内容如果没有发生变化,数字是不会滚动的,如果内容发生变化,数字又会重新进行滚动,这里修改下拉刷新的代码,模拟数据变化的情况,演示一下:

效果如下:

如果想要在刷新的时候,无论内容是否有变化都要执行滚动动画的话,可以在布局文件中,NumberRunningTextView 的配置中,将 runWhenChange 设置为 false 即可,此时,无论内容是否有变化,都会执行滚动动画,效果如下:

修改帧数

NumberRunningTextView默认是30帧,如果需要修改帧数,可以在布局文件中,NumberRunningTextView的配置中,将frameNum设置为自己想要的帧数。

源码解析

NumberRunningTextView 的原理其实很简单,只是将一个数字除以帧数(默认是30帧),分成每段固定的大小进行递增。

首先介绍下 NumberRunningTextView 自定义的属性:

NumberRunningTextView 继承于 TextView:

当调用 setContent()方法 时,里面做了相应的判断。

如果 runWhenChange 为 true,即当内容改变的时候才会滚动,进行如下判断,如果上次的内容为空(即第一次设置),则执行滚动,否则判断此次内容和上一次内容是否一致,如果一致,则不做处理,如果两次内容不一致,即内容发生了变化,记录当前的内容,并执行相应的滚动操作。

useAnimByType()方法 只是用于判断内容的类型,并执行相应的动画,NumRunningTextView 的核心为 playMoneyAnim() 和 playNumAnim()

下面对这两个方法进行解析:

1. 先对传入的字符串进行修改,如果有含有逗号或者负号,则去除逗号和负号;

2. 对字符串进行格式转换,如果转换出现异常,则直接调用 setText()方法 设置内容;

3. 如果传入的数字是0,则不用使用滚动动画,直接调用 setText() 设置内容;

4. 如果传入的是正确的金额数字,将数字除以帧数 frameNum,得到每一帧的大小(间隔),通过使用 Handler 的 sendMessage,传递当前内容的类型和每一帧数的大小,在 Handler 的 handleMessage()方法 中进行相应的处理。其中的 threadPool 为含有一个线程的线程池。threadPool = Executors.newFixedThreadPool(1);

Handler 中的相应处理:

handleMessage()方法 中,根据内容的类型进行相应的处理。

1. 根据是否使用逗号进行格式化,显示每帧增加后的数字;

2. 如果其小于 finalMoneyNum 目标数字(最终的数字),则继续调用 sendMessage()方法,形成递归操作,直至等于或大于目标数字;

3. 达到目标数字后,根据是否需要使用逗号进行格式化显示最终的效果

其中 formatter = new DecimalFormat(“0.00”);// 格式化金额,保留两位小数,用于使 double 类型数字保留两位小数。

到这里具体的设计思路应该都清楚了,其实就是通过使用 handler 不断发消息,形成递归,让数字进行递增,当达到最终的数字的时候,就停止发送消息,直接设置最终的内容。playNumAnim() 也是一样的思路,在这里就不重复说明了,感觉自己的写的注释已经足够详细了,顺便贴一下 playNumAnim() 的方法。

handler 中对应的处理:

到这里为止,NumberRunningTextView 的使用介绍和源码解析就结束了。下面介绍该控件的导入方式.

导入方式

在项目根目录下的 build.gradle 中的 allprojects{} 中,添加 jitpack 仓库地址,如下:

打开app的module中的build.gradle,在 dependencies{} 中,添加依赖,如下:

源码github地址:

https://github.com/chaychan/PowerfulViewLibrary.git

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: