转载请注明出处:王亟亟的大牛之路
最近的上海简直热热热,我短袖短裤了还是热。。。
因为明天又有事不上班所以今天早上赶紧赶一篇内容出来(还好有想好些什么不然又要 Go Die了)
这边继续安利下 我的收纳库:https://github.com/ddwhan0123/Useful-Open-Source-Android 方便大家找资料,安全无毒
传统的 登陆界面总有那些 点击发送验证码然后等待接受的一个计时操作,今天就上一个类似的实现(不用传统方法咯)
先看下效果:
貌不惊人,我们先来看看传统的Handler或者TimerTask是怎么操作的
一、采用Handle与线程的sleep(long)方法
Handler主要用来处理接受到的消息。这只是最主要的方法,当然Handler里还有其他的方法供实现,有兴趣的可以去查API,这里不过多解释。
1. 定义一个Handler类,用于处理接受到的Message。
Handler handler = new Handler() {
public void handleMessage(Message msg) {
// 要做的事情
super.handleMessage(msg);
}
};
- 新建一个实现Runnable接口的线程类,如下:
public class MyThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(1000);// 线程暂停1秒,单位毫秒
Message message = new Message();
message.what = 1;
handler.sendMessage(message);// 发送消息
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
- 在需要启动线程的地方加入下面语句:
new Thread(new MyThread()).start();
二、采用Handler与timer及TimerTask结合的方法
定义定时器、定时器任务及Handler句柄
private final Timer timer = new Timer();
private TimerTask task;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
// 要做的事情
super.handleMessage(msg);
}
};
初始化计时器任务
task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
启动定时器
timer.schedule(task, 2000, 2000);
这样的代码一样能做到如此,但是很麻烦 Why?因为handler要处理许多我们的异步行为,能往里面少丢东西就少丢吧,所以就自定义一个TextView来解决这个问题吧!!
包结构:
就一个自定义View和自定义标签的XML,要你放入自己的项目也很方便。
我们来看下如何使用
<wjj.com.countingtextview.countingTextView
android:id="@+id/countingText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
首先在XML里做一些初始化的行为,当然因为是继承于TextView所以你要用java代码初始化也行。
然后获取对象
countingText1 = (countingTextView) findViewById(R.id.countingText1);
接下来,设置下时间逻辑就OK啦 SO EASY 总比 handler还要开线程简单吧?
countingText1.setInterpolator(new LinearInterpolator());
countingText1.animateFromZero(60, 60000);
具体的一行行代码就不一一解释了,源码中对于重要的方法都有了注解,这边再把其他一些设置的方法来给大家解释下
//从startValue到endValue的动画过程
animateText(Integer startValue, Integer endValue)
//从0到endValue的动画过程
animateFromZero(Integer endValue)
//设置结束值
setEndValue(int endValue)
//设置开始值
setStartValue(int startValue)
//设置插值器
setInterpolator(TimeInterpolator interpolator)
不一句句读源码了,这里贴一段作为原理解释
public void animateText(Integer startValue, Integer endValue) {
setStartValue(startValue);
setEndValue(endValue);
ValueAnimator animator = ValueAnimator.ofInt(startValue, endValue);
animator.setInterpolator(getInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
setText(String.format(getFormat(), animation.getAnimatedValue()));
}
});
animator.setEvaluator(new TypeEvaluator<Integer>() {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
return Math.round(startValue + (endValue - startValue) * fraction);
}
});
animator.setDuration(getDuration());
animator.start();
}
默认调用设置开始,结束值然后使用ValueAnimator动画进行持续的刷新UI直到到最大值为止,时间区间由getDuration()方法来控制。
项目地址:https://github.com/ddwhan0123/BlogSample/tree/master/Countingtextview
下载地址:https://github.com/ddwhan0123/BlogSample/blob/master/Countingtextview/Countingtextview.zip