您的位置:首页 > 其它

你还在使用Handler做计时器么?来一个自定义TextView解决这些困扰吧!

2016-05-05 10:51 507 查看

转载请注明出处:王亟亟的大牛之路

最近的上海简直热热热,我短袖短裤了还是热。。。

因为明天又有事不上班所以今天早上赶紧赶一篇内容出来(还好有想好些什么不然又要 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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: