在开发中,前几天碰到了需要实现的一个特效——TextView文本闪烁
首先想到的是使用线程Timer,但是搜了很多大牛的博客使用线程发现都无法满足我的要求,因为在线程管理上是有难度的因为TextView的闪烁是可以暂停的,还可以继续闪烁,在这里还需要说下的是,其实这个功能实现非常简单,只需要一些基础知识就可以了,写这篇博客也是因为自己基础不是很扎实而稳固一下。回归正题,大家都会知道我们需要在子线程中更新UI是会出ANR这时我们需要用到Handler机制,这也是本文的中心;知道用了什么了之后就是该想想怎么用的问题了,废话不多说,两种——一handler自身的延时操作和使用handler发消息的机制延时发送。
方法一:handler自身的延时操作,主要代码如下:
<span style="white-space:pre"> </span>private TextView txt;
int[] colors = new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.GRAY,Color.CYAN };
int index = 0;
private boolean b = true;// 标识位,当多次点击start时不会出现闪烁变快
private Runnable run = new Runnable() {
public void run() {
index += 1;
if (index == colors.length) {
index = 0;// 颜色轮循的起点(不移除一直运行)
}
txt.setTextColor(colors[index]);
mHandler.postDelayed(run, 1000); // 调用自己延时5秒发送实现循环
}
};
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.textView1);
}
public void DoBtn(View v) {
switch (v.getId()) {
case R.id.button1:
if (b) {
b = false;
mHandler.postDelayed(run, 1000);
}
break;
case R.id.button2:
mHandler.removeCallbacks(run);
b = true;
break;
default:
break;
}
}
需要解释下的就是,这里的文字闪烁,闪烁的功能实现其实也分很多种,因为这里我的功能只需实现改变颜色就可以,如果需要其它跟炫更酷的样式可以使用动画或者其它方法,都应该是可以的,重点是使用到handler延时操作并在子线程中调用自身达到循环,还有就是标识位,因为多次点击闪烁开始会让闪烁变快这显然不是我们想要的。
方法二:使用handler发消息的机制,主要代码如下:
private TextView txt;
private Message msg = Message.obtain();
int[] colors = new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.GRAY,Color.CYAN };//颜色数大于等于2即可
int index = 0;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
index += 1;
if (index == colors.length) {
index = 0;//颜色轮循的起点(不移除一直运行)
}
txt.setTextColor(colors[index]);
mHandler.sendEmptyMessageDelayed(1, 1000);//延时调用自己实现自我循环
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.textView1);
}
public void DoBtn(View v) {
switch (v.getId()) {
case R.id.button1:
if (!mHandler.hasMessages(1)) {//判断是否已经发过此消息
mHandler.sendEmptyMessage(1);
}
mHandler.sendEmptyMessageDelayed(1, 1000);
break;
case R.id.button2:
mHandler.removeMessages(1);//移除此消息
break;
default:
break;
}
}
在这里其实可以看出来与上面的方法大同小异,都是延时调用自己,至于为什么,这里可以从postDelay方法调到源码中一看究竟;
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
从这段源码可以看出我们在使用handler延时操作的时候其实最后还是让handler在延时发送消息,只不过这个发消息的操作让handler帮我们做了,关于handler的源码详细介绍这里就不赘述了,相信很多大牛的博客都有写到,关于文本闪烁的实现的简单应用也就介绍到这里,也希望与大家多多交流学习!