在看本文前,请先阅读android学习16#–学习canvas.drawText ,因为掌握文字的绘制逻辑是本文的基础。
先来看下效果图:
实现功能:
1. 滚动方向有两种:水平跟垂直,可以xml中配置
2. 滚动文字字体颜色、字体大小、字体背景色都可以配置。
具体的原理不多说了,看主要源码:
public class AdvancedRollingTextView extends TextView {
private String textStr;
private float textSize;
private int colorFont;/*字体颜色*/
private int duration;/*单位时间(ms)移动*/
private int speed = 1;/*单位时间移动距离(像素)*/
private int w = 0;
private int h = 0;
private int offset = 0;/*滚动像素*/
private int offset_max = 0;/*最大滚动范围*/
private int rollorientation;/*滚动方向*/
private int rectLeft = 0;/*控件x坐标*/
private int rectTop = 0;/*控件y坐标*/
private float baseLine = 0;
private float descent = 0;
private Paint paint;
private Rect bound;
public AdvancedRollingTextView(Context context) {
super(context);
}
public AdvancedRollingTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AdvancedRollingTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.AdvancedRollingTextView);
rectLeft = typeArray.getInt(R.styleable.AdvancedRollingTextView_textRectLeft, 0);
rectTop = typeArray.getInt(R.styleable.AdvancedRollingTextView_textRectTop, 50);
speed = typeArray.getInt(R.styleable.AdvancedRollingTextView_speed, 1);
duration = typeArray.getInt(R.styleable.AdvancedRollingTextView_duration, 20);
rollorientation = typeArray.getInt(R.styleable.AdvancedRollingTextView_rollorientation, 0);
colorFont = getResources().getColor(R.color.colorFont);
textStr = this.getText().toString();
textSize = this.getTextSize();
paint = new Paint();
paint.setTextSize(textSize);
paint.setColor(colorFont);
bound = new Rect();
paint.getTextBounds(textStr, 0, textStr.length(), bound);
startPolling();
}
public void initAdvancedRollingText(String text) {
textStr = text;
}
public void delay(int ms) {
try {
Thread.currentThread();
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void startPolling() {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
postInvalidate();
if(offset>offset_max) {
offset=0;
delay(500);
}
//Log.i(" ## TimerTask ##", "offset: "+offset);
}
}, 0, duration);
}
@Override
protected void onDraw(Canvas canvas) {
float x=0;
float y=0;
offset+=speed;
//Log.i(" ## onDraw ##", "offset: "+offset);
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
/*计算descent*/
descent = fontMetrics.descent;
/*计算baseline,其中rectTop是控件顶部到父view的距离*/
baseLine = -fontMetrics.top + rectTop;
/*获取字符串宽高*/
w = bound.width();
h = bound.height();
if(0 == rollorientation) {//垂直滚动
offset_max = h+(int) descent;
x = rectLeft;
y = baseLine - offset;
} else {//水平滚动
offset_max = w;
x = rectLeft - offset;
y = baseLine;
}
canvas.drawText(textStr, x, y, paint);
}
}