这期我们来实现一个能够实现字体变色的ViewPager指示器:
自定义属性:
<resources>
<declare-styleable name="ColorTrackTextView">
<attr name="originColor" format="color"/>
<attr name="changecolor" format="color"/>
</declare-styleable>
</resources>
定义ColorTrackTextView继承TextView,完整代码:
public class ColorTrackTextView extends androidx.appcompat.widget.AppCompatTextView {
private Paint mOringinPaint;
private Paint mChangePaint;
private float mCurrentProgress = 0.5f; //当前的进度
//实现不同朝向
private Direction mDirection;
public enum Direction{
LEFT_TO_RIGHT,RIGHT_TO_LEFT
}
public ColorTrackTextView(Context context) {
this(context, null);
}
public ColorTrackTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorTrackTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint(context, attrs);
}
private void initPaint(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);
int originColor = array.getColor(R.styleable.ColorTrackTextView_originColor, getTextColors().getDefaultColor());
int changeColor = array.getColor(R.styleable.ColorTrackTextView_changecolor, getTextColors().getDefaultColor());
mOringinPaint = getPaintByColor(originColor);
mChangePaint = getPaintByColor(changeColor);
array.recycle();
}
private Paint getPaintByColor(int color) {
Paint paint = new Paint();
paint.setColor(color);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setTextSize(getTextSize());
return paint;
}
//利用clipRect的API可以裁剪 左边用一个画笔去画, 右边用另一个画笔去画 不断的改变中间值
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);
//绘制不变色的
int middle= (int) (mCurrentProgress*getWidth());
if (mDirection==Direction.LEFT_TO_RIGHT){
drawtext(canvas,mChangePaint,0,middle);
drawtext(canvas,mOringinPaint,middle,getWidth());
}else {
drawtext(canvas,mOringinPaint,getWidth()-middle,getWidth());
drawtext(canvas,mChangePaint,0,getWidth()-middle);
}
}
private void drawtext(Canvas canvas,Paint paint,int start,int end){
canvas.save();
//canvas.clipRect()裁剪区域
Rect rect = new Rect(start, 0, end, getHeight());
canvas.clipRect(rect);
String text = getText().toString();
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
//获取字体宽度
int x = getWidth() / 2 - bounds.width() / 2;
//基线
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
int baseline = getHeight() / 2 + dy;
canvas.drawText(text, x, baseline, paint);
canvas.restore(); //画布释放
}
public void setDirection(Direction direction){
this.mDirection=direction;
}
public void setCurrentProgress(float currentProgress){
this.mCurrentProgress=currentProgress;
invalidate();
}
}
在构造函数中调用initPaint完成自定义属性和画笔Paint 的设置,在onDraw中实现文字的变色,setDirection和setCurrentProgress函数 用于外部 设置 变色的 方向和 动画的 进度。
MainActivity完整代码:
public class MainActivity extends AppCompatActivity {
private ColorTrackTextView mColorTrackTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mColorTrackTextView=(ColorTrackTextView)findViewById(R.id.Color_Track_tv);
}
public void leftToright(View v){
mColorTrackTextView.setDirection(ColorTrackTextView.Direction.LEFT_TO_RIGHT);
ValueAnimator valueAnimator=ObjectAnimator.ofFloat(0,1);
valueAnimator.setDuration(2000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentprogress=(float)animation.getAnimatedValue();
mColorTrackTextView.setCurrentProgress(currentprogress);
}
});
valueAnimator.start();
}
public void rightToleft(View v){
mColorTrackTextView.setDirection(ColorTrackTextView.Direction.RIGHT_TO_LEFT);
ValueAnimator valueAnimator=ObjectAnimator.ofFloat(0,1);
valueAnimator.setDuration(2000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentprogress=(float)animation.getAnimatedValue();
mColorTrackTextView.setCurrentProgress(currentprogress);
}
});
valueAnimator.start();
}
}
MainActivity中写两个方向的按钮。
实现效果如下:
源码下载:https://download.youkuaiyun.com/download/nmgsyps2017/20554204?spm=1001.2014.3001.5503