一、自定义属性的声明
<!--彩色跑道 TextView-->
<declare-styleable name="ColorTrackTextView">
<attr name="ctOriginTextColor" format="color" />
<attr name="ctChangeTextColor" format="color" />
</declare-styleable>
二、编码ColorTrackTextView.java
public class ColorTrackTextView extends AppCompatTextView {
private Paint mOriginPaint;
private Paint mChangePaint;
//当前进度
private float mCurrentProgress;
//默认朝向
private Directory mCurrentDirectory = Directory.LEFT_TO_RIGHT;
//朝向
public enum Directory {
LEFT_TO_RIGHT,
RIGHT_TO_LEFT
}
public ColorTrackTextView(Context context) {
this(context, null);
}
public ColorTrackTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorTrackTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint(context, attrs);
}
private void initPaint(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);
int mOriginTextColor = typedArray.getColor(R.styleable.ColorTrackTextView_ctOriginTextColor,
getTextColors().getDefaultColor());
int mChangeTextColor = typedArray.getColor(R.styleable.ColorTrackTextView_ctChangeTextColor,
getTextColors().getDefaultColor());
typedArray.recycle();
//根据自定义的颜色来创建画笔
mOriginPaint = getPaintByColor(mOriginTextColor);
mChangePaint = getPaintByColor(mChangeTextColor);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//根据当前进度,获取当前中间值
int middle = (int) (mCurrentProgress * getWidth());
//根据朝向,绘制TextView
if (mCurrentDirectory == Directory.LEFT_TO_RIGHT) {
//当前朝向为 从左到右
drawText(canvas, mOriginPaint, middle, getWidth());
drawText(canvas, mChangePaint, 0, middle);
} else {
//当前朝向 从右到左
drawText(canvas, mOriginPaint, 0, getWidth() - middle);
drawText(canvas, mChangePaint, getWidth() - middle, getWidth());
}
}
/**
* 绘制TextView
*/
private void drawText(Canvas canvas, Paint textPaint, int start, int end) {
//保存画布状态
canvas.save();
Rect rect = new Rect(start, 0, end, getHeight());
canvas.clipRect(rect);
//获取文字
String text = getText().toString();
Rect bounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), bounds);
//获取字体的宽度
int x = getWidth() / 2 - bounds.width() / 2;
//获取基线
Paint.FontMetricsInt fontMetricsInt = textPaint.getFontMetricsInt();
int dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
int baseLine = getHeight() / 2 + dy;
canvas.drawText(text, x, baseLine, textPaint);
//释放画布状态,既恢复Canvas旋转,缩放等之后的状态。
canvas.restore();
}
private Paint getPaintByColor(int textColor) {
//创建画笔
Paint paint = new Paint();
//设置画笔颜色
paint.setColor(textColor);
//设置抗锯齿
paint.setAntiAlias(true);
//设置防抖动
paint.setDither(true);
//设置字体大小
paint.setTextSize(getTextSize());
return paint;
}
/**
* 设置方向
*
* @param directory
*/
public synchronized void setDirectory(Directory directory) {
this.mCurrentDirectory = directory;
}
/**
* 设置进度
*
* @param currentProgress
*/
public synchronized void setCurrentProgress(float currentProgress) {
this.mCurrentProgress = currentProgress;
invalidate();
}
/**
* 设置画笔颜色
*
* @param changeColor
*/
public synchronized void setChangeColor(int changeColor) {
this.mChangePaint.setColor(changeColor);
}
public synchronized void setOriginColor(int originColor) {
this.mOriginPaint.setColor(originColor);
}
}
三、使用:
xml:
<.......ColorTrackTextView
android:id="@+id/track_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/app_name"
android:textSize="22sp"
app:ctChangeTextColor="@color/colorAccent"
app:ctOriginTextColor="@color/colorPrimary" />
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="从左到右"/>
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="从右到左"/>
activity:
public class CustomViewActivity extends AppCompatActivity {
@BindView(R.id.track_text_view)
ColorTrackTextView trackTextView;
@BindView(R.id.btn1)
Button btn1;
@BindView(R.id.btn2)
Button btn2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_view);
ButterKnife.bind(this);
}
@OnClick({R.id.btn1, R.id.btn2})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.btn1:
ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 1);
valueAnimator.setDuration(2000);
valueAnimator.setInterpolator(new DecelerateInterpolator());
trackTextView.setDirectory(ColorTrackTextView.Directory.LEFT_TO_RIGHT);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedValue = (float) animation.getAnimatedValue();
trackTextView.setCurrentProgress(animatedValue);
}
});
valueAnimator.start();
break;
case R.id.btn2:
ValueAnimator valueAnimator2 = ObjectAnimator.ofFloat(0, 1);
valueAnimator2.setDuration(2000);
valueAnimator2.setInterpolator(new DecelerateInterpolator());
trackTextView.setDirectory(ColorTrackTextView.Directory.RIGHT_TO_LEFT);
valueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedValue = (float) animation.getAnimatedValue();
trackTextView.setCurrentProgress(animatedValue);
}
});
valueAnimator2.start();
break;
}
}
}