前段时间在网上浏览帖子,发现一篇求助的帖子(链接忘记了),关于跑马灯和图片切换动画冲突的问题。
界面上有图片切换,切换带动画,同时有跑马灯在运行,当图片切换运行切换动画的时候,跑马灯总是会卡一下,我的第一反应就是图片解码的问题,
于是我写了个测试程序,在显示图片这块加入了图片压缩解码、缓存以及预加载,再运行下,跑马灯会好些,但是还是会有点卡,随后我将图片切换的动画去掉,
跑马灯就不再卡了;
仔细想了下,为何会卡呢,两个动画为何会卡,都是在UI线程中运行的动画,这就是问题所在了,因为图片切换动画是在UI线程中运行,跑马灯动画也要在
UI线程中运行,而看看代码,自定义跑马灯里面用的是不断刷新UI实现的,一个应用程序就一个UI线程,跑马灯频繁刷新UI,而当图片切换的时候这个动画也在运行,阻塞了
UI的刷新,所以导致跑马灯在这里卡了一下;
问题找到了,就是动画阻塞了跑马灯的刷新,要解决这两个问题就两个方向,第一种修改动画,第二种修改跑马灯,但是动画不管怎么修改还是会阻塞UI的刷新,所以
只能在跑马灯这里下功夫了,既然跑马灯在刷新UI的时候阻塞了,那有什么办法实现不用刷新UI线程的跑马灯呢,答案是肯定的,办法就是让TextView自己刷新,而不是去刷新
整个UI线程,所以这里就要自定义TextView了,实现方法也有两种,一种是采用View的scrollTo方法,另外一种是canvas.drawText方法,这里用第二种,完整代码:
package com.yyu.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* @ClassName: MarqueeTextView
* @Description: TODO
* @author yan.yu
* @date 2014-3-19 上午9:02:30
*/
public class MarqueeTextView extends TextView
{
private Paint paint = null;
private float textLenght = 0;//字符串占的宽度
private float textHeight = 0;//字符串占的高度
private int speed = 2;//移动速度
private float xPosition = 0;//x方向位移
private float yposition = 0;//y方向位移
private int scrollWidth = 0;//允许移动的水平范围
private int scrollHeight = 0;//允许移动的垂直范围
private int color = 0;
private String text = "";
private boolean isScroll = false;
private String direction = "left";
/**
* <p>Title: </p>
* <p>Description: </p>
* @param context
* @param attrs
*/
public MarqueeTextView(Context context)
{
super(context);
// TODO Auto-generated constructor stub
paint = super.getPaint();
}
public MarqueeTextView(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
paint = super.getPaint();
}
public String getDirection()
{
return direction;
}
public void setDirection(String direction)
{
this.direction = direction;
}
public int getSpeed()
{
return speed;
}
public void setSpeed(int speed)
{
this.speed = speed;
}
public void setTextColor(int color)
{
this.color = color;
}
public void startScroll()
{
if(color != 0)
paint.setColor(color);
isScroll = true;
invalidate();
}
public void stopScroll()
{
isScroll = false;
}
/**
*callbacks
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
*callbacks
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom)
{
// TODO Auto-generated method stub
super.onLayout(changed, left, top, right, bottom);
text = super.getText().toString();
scrollWidth = getWidth();
scrollHeight = getHeight();
if(direction.equals("left"))
{
textLenght = paint.measureText(text);
xPosition = scrollWidth;//left
yposition = getTextSize() + getPaddingTop();
}
else if(direction.equals("right"))
{
textLenght = paint.measureText(text);
xPosition = -textLenght;//right
yposition = getTextSize() + getPaddingTop();
}
else if(direction.equals("up"))
{
textHeight = getTextSize();
yposition = scrollHeight + textHeight;//up
}
else if(direction.equals("down"))
{
textHeight = getTextSize();
yposition = 0;//down
}
}
/**
*callbacks
*/
@Override
protected void onDraw(Canvas canvas)
{
// TODO Auto-generated method stub
if(isScroll)
{
if(direction.equals("left"))
{
scrollToLeft(canvas);
}
else if(direction.equals("right"))
{
scrollToRight(canvas);
}
else if(direction.equals("up"))
{
scrollToUp(canvas);
}
else if(direction.equals("down"))
{
scrollToDown(canvas);
}
invalidate();
}
else
super.onDraw(canvas);
}
private void scrollToLeft(Canvas canvas)
{
canvas.drawText(text, 0, text.length(), xPosition, yposition, paint);
xPosition -= speed;
if(xPosition <= -textLenght)
xPosition = scrollWidth;
}
private void scrollToRight(Canvas canvas)
{
canvas.drawText(text, 0, text.length(), xPosition, yposition, paint);
xPosition += speed;
if(xPosition >= scrollWidth)
xPosition = -textLenght;
}
private void scrollToUp(Canvas canvas)
{
canvas.drawText(text, 0, text.length(), xPosition, yposition, paint);
yposition -= speed;
if(yposition <= 0)
yposition = scrollHeight + textHeight;
}
private void scrollToDown(Canvas canvas)
{
canvas.drawText(text, 0, text.length(), xPosition, yposition, paint);
yposition += speed;
if(yposition >= scrollHeight + textHeight)
yposition = 0;
}
}