网上的很多的教程都是通过更改TextView的属性进行跑马灯的设计。这样做有很多的缺点:
1、如果TextView没有获取焦点,那么跑马灯的效果无法实现。
2、如果文本长度小于TextView的宽度,跑马灯的效果无法实现。
3、需要设置很多属性,麻烦。
还有很多教程是通过重写TextView的方式使TextView获得焦点,但是没有解决上面的几个问题。
本教程也是通过重写TextView的方式,准确的说是通过重写View的方式实现跑马灯。
使用到的技术:
1、Paint的使用;
2、Canvas中的drawText方法;
3、线程;
Paint:就是我们俗称的画笔,Android提供了很多的方法对Paint进行设置:
setAntiAlias: 设置画笔的锯齿效果。
setColor: 设置画笔颜色。
setARGB: 设置画笔的a,r,p,g值。
setAlpha: 设置Alpha值。
setTextSize: 设置字体尺寸。
setStyle: 设置画笔风格,空心或者实心。
setStrokeWidth: 设置空心的边框宽度。
getColor: 得到画笔的颜色。
getAlpha: 得到画笔的Alpha值。
Canvas:提供了如下的方法
Canvas(): 创建一个空的画布,可以使用setBitmap()方法来设置绘制具体的画布。
Canvas(Bitmap bitmap): 以bitmap对象创建一个画布,则将内容都绘制在bitmap上,因此bitmap不得为null。
Canvas(GL gl): 在绘制3D效果时使用,与OpenGL相关。
drawColor: 设置Canvas的背景颜色。
setBitmap: 设置具体画布。
clipRect: 设置显示区域,即设置裁剪区。
isOpaque:检测是否支持透明。
rotate: 旋转画布
setViewport: 设置画布中显示窗口。
skew: 设置偏移量。
线程:这方面的资料很多。
以下是代码:
package net.songsoft.paomadeng; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.widget.TextView; /** * <br> * CreateDate: 2014-3-25<br> * Copyright: Copyright(c)<br> * Company: songsoft<br> * @author 宋志辉 * @version V1.0.0 * @Description 跑马灯的实现类 */ public class MarqueeTextView extends TextView implements Runnable { private Paint m_paint; private int width; private String src; /** * * @return src * @Description 获取字符串 * 2014-3-26::宋志辉::创建此方法</br> */ public String getSrc() { return src; } /** * * @param src * @Description 设置字符串 * 2014-3-26::宋志辉::创建此方法</br> */ public void setSrc(String src) { this.src = src; } /** * <br> * @param context <br> * @Description 构造函数,对跑马灯的数据进行初始化 * 2014-3-25::宋志辉::创建此构造方法<br> */ public MarqueeTextView(Context context) { super(context); width = 320; m_paint = new Paint(); new Thread(this).start(); } /** * * @param strText * @return * @Description 获取字符的宽度和高度 * 2014-3-25::宋志辉::创建此方法</br> */ Rect GetStringRect(String strText) { Rect rect = new Rect(); m_paint.getTextBounds(strText, 0, strText.length(), rect); return rect; } /** * * @param canvas * @param txtStr * @Description 跑马灯的效果 * 2014-3-25::宋志辉::创建此方法</br> */ void marquee(Canvas canvas, String txtStr) { String txtStr2 = txtStr.substring(0, txtStr.length()) ; Rect rect = GetStringRect(txtStr); int len = txtStr.length(); while((width + rect.width() > 320) && (len > 0)) { rect = GetStringRect(txtStr.substring(0, len)); len -= 1; } m_paint.setColor(Color.BLACK); String txtLeft = txtStr.substring(len, txtStr.length()); if (!txtLeft.equals("")) { canvas.drawText(txtLeft, 20, 40, m_paint); } String txtRight = txtStr.substring(0, len); if (!txtRight.equals("")) { canvas.drawText(txtRight, width, 40, m_paint); } if(width>20){ width-=1; }else{ width=320; } } /** * * @param canvas * @see android.view.View#onDraw(android.graphics.Canvas) * @Description 重绘 * 2014-3-25::宋志辉::创建此方法<br> */ @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); marquee(canvas, this.getSrc()); } /** * * @see java.lang.Runnable#run() * @Description 线程,刷新界面 * 2014-3-25::宋志辉::创建此方法<br> */ @Override public void run() { // TODO Auto-generated method stub while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(10); } catch (Exception e) { // TODO: handle exception Thread.currentThread().interrupt(); } postInvalidate(); } } }