Android 开发 自定义跑马灯 TextView

在项目开发中,有次需要用到跑马灯,使用了系统自带的跑马灯,发现会有点问题.然后就考虑重写了一个跑马灯 textview.

主要思路是 自定义一个画笔工具,自己画出 textview

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
public class MarqueeTextView extends View {

private static String TAG = MarqueeTextView.class.getSimpleName();

private String mContent;

private ValueAnimator mAnimator;

private Paint mPaint;
private int mOffset;
private int mBaseLine;
private Rect mTargetRect;
private int mTextWidth = 0;

public MarqueeTextView(Context context) {
super(context);
init();
}

public MarqueeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init() {
mPaint = new Paint();
mPaint.setTextSize(getContext().getResources().getDimension(R.dimen.sp_15));
mPaint.setColor(Color.RED);
mPaint.setTextAlign(Paint.Align.LEFT);
mPaint.setAntiAlias(true);

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mContent == null) {
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
return;
}


Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
int height = fontMetrics.bottom - fontMetrics.top + getPaddingBottom() + getPaddingTop();
setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));

int top = getPaddingTop();
int bottom = top + fontMetrics.bottom - fontMetrics.top;
int left = getPaddingLeft() + mOffset;
int right = left + mTextWidth;
if (mTargetRect == null) {
mTargetRect = new Rect();
}
mTargetRect.set(left, top, right, bottom);
mBaseLine = (mTargetRect.bottom + mTargetRect.top - fontMetrics.bottom - fontMetrics.top) / 2;
mAnimator.cancel();
if (mTextWidth > getMeasuredWidth()) {
mAnimator.start();
}

}

@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if(visibility == View.VISIBLE){
start();
}else{
cancel();
}
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if (mContent == null || mTargetRect == null) {
return;
}

mTargetRect.left = getPaddingLeft() + mOffset;
mTargetRect.right = mTargetRect.left + mTextWidth;
canvas.drawText(mContent, mTargetRect.left, mBaseLine, mPaint);
}

public void setText(String text) {
mContent = text;
mTextWidth = (int) (mPaint.measureText(mContent, 0, mContent.length())+1);
if(null == mAnimator){
mAnimator = ValueAnimator.ofFloat(0, mTextWidth);
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mOffset -= 2;
if (mOffset < -mTextWidth) {
mOffset = getWidth();
}
invalidate();
}
});
mAnimator.setRepeatCount(ValueAnimator.INFINITE);
mAnimator.setRepeatMode(ValueAnimator.REVERSE);
//5.为ValueAnimator设置目标对象并开始执行动画
mAnimator.setTarget(this);
mAnimator.setDuration((long) (mTextWidth));

}

}

public void start(){
if(null != mAnimator && mTextWidth > getMeasuredWidth()){
mAnimator.start();
}
}

public void cancel(){
if(null != mAnimator && mTextWidth > getMeasuredWidth()){
mAnimator.cancel();
}
}
}
Adhere to original technology sharing, your support will encourage me to continue to create!