自定义View——ViewPager和Layout实现字体变色效果

        这期我们来实现一个能够实现字体变色的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁铮的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值