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工程,可以在上面调整出需要的速度
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值