当前位置: 代码迷 >> Android >> Android自定义TextView实现跑马灯成效
  详细解决方案

Android自定义TextView实现跑马灯成效

热度:9   发布时间:2016-04-27 23:34:43.0
Android自定义TextView实现跑马灯效果
1、机顶盒应用中经常用到跑马灯效果,而自己绘制跑马灯效果的关键在于步长和刷新频率的控制,一般情况下,刷新频率不要大于16ms,因为16ms是保证不掉帧的关键时间点,所以就不会出现卡顿的现象,具体实现代码如下:

package com.example.marquee;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.os.Handler;import android.text.TextPaint;import android.text.TextUtils;import android.util.AttributeSet;import android.view.View;public class CustomTextView extends View {    /**     * 界面刷新时间(ms)     */    public static final int INVALIDATE_TIME = 15;    /**     * 每次移动的像素点(px)     */    public static final int INVALIDATE_STEP = 4;    /**     * 一次移动完成后等待的时间(ms)     */    public static final int WAIT_TIME = 1500;    /**     * 滚动文字前后的间隔     */    private String space = "              ";    private String drawingText = "";    private TextPaint paint;    public boolean exitFlag;    private float textWidth;    private String _mText;    private int posX = 0;    private float posY;    private int width;    private RectF rf;    private Handler mHandler = new Handler();    public CustomTextView(Context context) {        this(context, null);    }    public CustomTextView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CustomTextView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initView();    }    private void initView() {        paint = new TextPaint();        paint.setAntiAlias(true);        paint.setColor(Color.WHITE);        paint.setTextSize(30F);        rf = new RectF(0, 0, 0, 0);    }    public void setText(String text) {        this._mText = text;        this.drawingText = _mText;        layoutView();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);        layoutView();    }    private void layoutView() {        width = getWidth();        rf.right = width;        rf.bottom = getHeight();        textWidth = paint.measureText(_mText, 0, _mText.length());        posY = getTextDrawingBaseline(paint, rf);    }    @Override    protected void onDraw(Canvas canvas) {        if (getVisibility() != View.VISIBLE || TextUtils.isEmpty(drawingText)) {            return;        }        canvas.save();        canvas.drawText(drawingText, 0, drawingText.length(), posX, posY, paint);        canvas.restore();    }    private Runnable moveRun = new Runnable() {        @Override        public void run() {            if(width >= textWidth){                return;            }            drawingText = _mText + space + _mText;            posX -= INVALIDATE_STEP;            if(posX >= -1 * INVALIDATE_STEP / 2 && posX <= INVALIDATE_STEP / 2){                mHandler.postDelayed(this, WAIT_TIME);                invalidate();                return;            }            if (posX < -1 * textWidth - paint.measureText(space, 0, space.length())) {                posX = INVALIDATE_STEP;            }            invalidate();            if(!exitFlag){                mHandler.postDelayed(this, INVALIDATE_TIME);                return;            }            posX = 0;        }    };    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        stopMove();    }    @Override    public void onWindowFocusChanged(boolean hasWindowFocus) {        super.onWindowFocusChanged(hasWindowFocus);        layoutView();        startMove();    }    private void stopMove() {        exitFlag = true;        mHandler.removeCallbacksAndMessages(null);    }    public void startMove() {        exitFlag = false;        mHandler.post(moveRun);    }    /**     * 获取绘制文字的baseline     *     * @param paint     * @param targetRect     * @return     */    public static float getTextDrawingBaseline(Paint paint, RectF targetRect) {        if (paint == null || targetRect == null) {            return 0;        }        Paint.FontMetrics fontMetric = paint.getFontMetrics();        return targetRect.top + (targetRect.height() - fontMetric.bottom + fontMetric.top) / 2.0f - fontMetric.top;    }}


调用代码:
package com.example.marquee;import android.app.Activity;import android.graphics.Color;import android.os.Bundle;import android.widget.RelativeLayout;public class MainActivity extends Activity {	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		RelativeLayout rl = new RelativeLayout(MainActivity.this);		setContentView(rl);		CustomTextView view = new CustomTextView(MainActivity.this);		view.setBackgroundColor(Color.GRAY);		view.setText("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");		rl.addView(view, 300, 100);	}}


大家可以根据自己的需要去调整步长,建议不要修改刷新间隔时间。

附件是Demo工程,可以在上面调整出需要的速度
  相关解决方案