一般我們做跑馬燈,都是使用 WebView 來實做,但是 WebView 的效能並不好,而其實 TextView 就有內建跑馬燈的功能了,但不好控制,所以還是自己寫程式碼來控制是最好的,接下來就讓我們看一下怎麼做吧!
而這篇文章是參考「自定义TextView跑马灯效果,可控制启动,停止,和速度(含源码)」一文改的,主要是原文在特定的情況下會有殘影產生,所以海芋加以改寫,程式碼如下:
public class MarqueeTextView extends TextView implements Runnable
{
public enum MarqueeDirection
{
LEFT, RIGHT
}
private volatile boolean m_bIsStop = false;
private int m_iTextWidth = 0;// 文字寬度
private boolean m_bIsMeasure = false;
private int m_iDistance = 1;
private int m_iSpeed = 25;
private int m_iScrollPosition = 0;
private MarqueeDirection m_Direction = MarqueeDirection.RIGHT;
public MarqueeTextView(Context context)
{
super(context);
setEllipsize(TruncateAt.MARQUEE);
setSingleLine(true);
onResume();
}
@Override
protected void onDraw(Canvas canvas)
{
if (!m_bIsMeasure)
{ // 文字寬度只要獲取一次就好啦!
getTextWidth();
startScroolFrom0();
m_bIsMeasure = true;
}
super.onDraw(canvas); // 先設定好再畫,才不會有殘影
}
public void onResume()
{
startScroll();
}
public void onPause()
{
stopScroll();
}
private void getTextWidth()
{
Paint paint = getPaint();
String str = getText().toString();
m_iTextWidth = (int) paint.measureText(str);
}
protected void startScroolFrom0()
{ // 跑馬燈初始值方向
if (m_Direction == MarqueeDirection.RIGHT)
m_iScrollPosition = -getWidth();
else
m_iScrollPosition = m_iTextWidth;
scrollTo(m_iScrollPosition, 0);
}
@Override
public void run()
{
if (m_bIsStop)
return;
// 跑馬燈初始值方向
if (m_Direction == MarqueeDirection.RIGHT)
m_iScrollPosition += m_iDistance;
else
m_iScrollPosition -= m_iDistance;
scrollTo(m_iScrollPosition,0);
if ((m_Direction == MarqueeDirection.RIGHT && getScrollX() >= m_iTextWidth) || // 由右向左捲
(m_Direction == MarqueeDirection.LEFT && getScrollX() <= -getWidth())) // 由左向右捲
{
startScroolFrom0();
}
postDelayed(this, m_iSpeed);
}
private void startScroll()
{
m_bIsStop = false;
removeCallbacks(this);
post(this);
}
private void stopScroll()
{
m_bIsStop = true;
removeCallbacks(this);
}
}