您的位置:首页 > 其它

TextSwitcher 跑马灯算法完善

2016-07-12 16:09 471 查看
作者:郑少锐,欢迎转载,也请保留这份申明,谢谢。


在上一篇博客中,虽然实现了textswitcher的跑马灯效果,但是用的是随便给几个值延时的,自己在调试的时候没问题,但交差之前,心虚的自己还是把它完善了再说,这里只讲完善算法,集体的可以看我上一篇的博客:

http://blog.csdn.net/u011418943/article/details/51871482

那么应该怎么完善呢?

这次我的想法是,既然我们能获取一行的大小了?为什么不获取字符串的长度或者最后一个字符是什么呢?然后根据是否已经到最后一行了,再让它上下翻滚不就可以了吗。

这里考虑到最后一个字符一般为标点符号,就算不是标点符号,字符总是会冲突的,所以,这里获取的是字符串的长度。用计算匹配 TextView 本身跑马灯的速度,从而获取是否已经到最后了。这样可以省下很多繁琐的判断。下面是程序,根据以前的程序来完善。

首先是定时器,计算TextView 一个字的滚动速度,设好定时时间,比如我的 600ms 。

Timer countTimer = new Timer();
countTimerTask coTimerTask = new countTimerTask();
countTimer.schedule(coTimerTask, 1,600);


那这个定时器有什么用?没错,既然我们是匹配长度,那肯定是一个字符串的指针的自加了,如:

private int indexCount = 0;
class countTimerTask extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
if (checkLastIndexFlag) {  //多行时,启动检测

indexCount++;  //游标位置自加
Log.d("zsr", "indexCount: "+indexCount);
msg = new Message();
msg.what = UPDATE_UP;
handler.sendMessage(msg);
}else {
indexCount = 0;
}
}
}


通过定时器发送一个消失,在消失中处理,我们的逻辑:

Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_TEXTSWITCHER:
updateText();
break;
case UPDATE_UP:

waterTextStatus = upshift(indexCount,stringLength);

break;
default:
break;
}

};
};


waterTextStatus 是判断是否为多行的,这个上篇讲过,我们来看看 upshif t的函数:

public boolean  upshift(int count,int length) {

length = length - 48 + (length/48)*10;

if (count >= length) {
count = 0;
checkLastIndexFlag = false;  //去掉定时
return false;
}else {
return true;
}
}


注意我们要滚动的主要是一行之后后面的剩余文字,所以这里我先让它 减去 48 ,然后根据多少行来乘以10,目的只是不让它一滚完就上移。这个可以自己设定。

当游标没有移动最有一个时,都是返回true,这时是不会上移的,只有匹配时,才会为false,然后提示线程上移动画。至于 checkLastIndexFlag 在哪里 为 true。别急,先看瘦身后的updateText :

private void updateText(){
if (this.dataflag == 1) {
if (this.reArrayList != null && this.reArrayList.size()>0) {
try {
subStr(reArrayList.get(resIndex), 48);
this.setText(this.reArrayList.get(resIndex));
Log.d("zsr", "size: "+subArrayList.size());
if (resIndex++ >= reArrayList.size()-1) {
resIndex = 0;
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}else {
this.setText(this.string);
}
}


是不是少了很多烦人的逻辑判断,只有一个就行, checkLastIndexFlag 还是在subStr 里面判断:

public  void subStr(String str, int subSLength)
throws UnsupportedEncodingException{
Log.d("zsr", "strbyte: "+str.toString().getBytes("GBK").length);
stringLength = str.toString().getBytes("GBK").length;
if (str.toString().getBytes("GBK").length > subSLength) {
int shi = str.toString().getBytes("GBK").length/subSLength;
int ge = str.toString().getBytes("GBK").length%subSLength;
Log.d("zsr", "shi/ge: "+shi+"  "+ge);
if (shi > 0 && ge != 0) {  //不小于一行,分开显示
//  检测时间
checkLastIndexFlag = true; //开始执行
}
}else {
subArrayList.add(str); //小于一行则正常显示
Log.d("zsr", "cannot read?");

}
}


同样是瘦身,但实现的效果更好。当然,你也可以参考让游标跑到检测字符串的最后一个,或者就是抓着长度来做文章。

当然,如有错误,也希望指出指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息