重学 Android 自定义 View 系列(四):文字变色

目标

通过 ColorTrackTextView 来展示一种文字进度条效果,其中一部分文本以原始颜色显示,另一部分文本以目标颜色显示,随着进度的变化,逐步改变文字颜色的展示。

最终效果如下:
在这里插入图片描述

1. 结构分析


  • 文本显示:该控件将展示文本内容,文本的颜色随着进度的变化而变化。
  • 进度条效果:文本的颜色变化会基于一个进度值(0f 到 1f),从一个颜色(原始颜色)逐渐过渡到另一个颜色(目标颜色)。
  • 支持方向:文本颜色的过渡可以是从左到右,也可以是从右到左。

2. 实现思路


  1. 初始化画笔:我们需要两个画笔,分别绘制未变化的颜色和变化后的颜色。
  2. 计算绘制位置:根据进度计算文本的变化区间和显示位置。
  3. 剪切区域:使用 canvas.clipRect() 来控制不同进度下文本显示的区域。
  4. 动态更新进度:通过设置进度值并调用 invalidate() 来刷新视图,使文本颜色过渡。

3. 关键技术点解析


我们用到了 Canvas 类的几个重要方法,特别是 clipRect()、save() 和 restore()。这些方法对于自定义绘制文本的效果至关重要。

自定义 TextView:通过继承 AppCompatTextView 来创建自定义控件。利用系统原有的属性,可以省去一些步骤

canvas.clipRect()

功能
canvas.clipRect() 方法用于限制 Canvas 上绘制内容的区域,即设置一个矩形区域作为画布的可绘制区域,只有在这个区域内的绘制操作才会被执行,超出该区域的部分会被裁剪掉。

因为我们要达到的目标是一个文字两种颜色,两种颜色需要分别绘制,因为不可能只绘制部分字体,这里使用 canvas.clipRect() 的目的就是把裁剪区域外的字体扔掉。也可以理解为 clipRect 就是一个剪刀。

方法

public void clipRect(int left, int top, int right, int bottom);
public void clipRect(Rect rect);
public void clipRect(float left, float top, float right, float bottom);

接受一个 Rect 对象 或四个坐标,直接定义裁剪矩形的区域。

canvas.save()

canvas.save() 会将当前的画布状态(包括变换矩阵、剪裁区域、画笔、绘制属性等)保存到栈中。这样,之后对画布的操作就不会影响到原本的画布状态,保证每次的绘制操作都是局部的。相当于记录个快照

方法

public int save();
public int save(int saveFlags);

保存当前画布的状态。带有标志位参数,可以指定保存哪些部分的状态,例如是否保存剪切区域、变换矩阵等。常用的标志位是 Canvas.ALL_SAVE_FLAG(保存所有状态)。

canvas.restore()

canvas.restore() 方法用于恢复上次保存的画布状态。你可以在绘制过程中做一些修改(如变换矩阵、裁剪区域等),然后恢复到之前的状态,继续进行绘制操作。

方法

public void restore();

通过 save() 方法保存了画布的状态之后,可以在需要时通过 restore() 恢复画布的状态,以便不影响后续绘制。

在 onDraw() 方法中,我们使用 save() 和 restore() 来保护每次对 Canvas 状态的修改不相互干扰。例如,每次使用 clipRect() 时,都先保存当前的画布状态,然后修改裁剪区域,完成绘制后,再调用 restore() 恢复原始状态,确保其他绘制操作不受影响。

save() 和 restore() 两个方法的作用可能在理解起来有点困难,虽然 Canvas 本身是一个单一的对象,但通过 save() 和 restore(),可以在 同一个 Canvas 上创建多个“画布状态”。只可意会不可言传,MD,好玄幻。

这两个方法可以理解成是 “记住”和“恢复” 画布状态的工具。

4. 定义自定义属性


定义两种颜色:文本的原始颜色,和改变的颜色。这些属性可以通过 res/values/attrs.xml 文件来定义:

    <declare-styleable name="ColorTrackTextView">
        <attr name="originColor" format="color"/>
        <attr name="changeColor" format="color"/>
    </declare-styleable>

5. 初始化视图元素


初始化画笔和两种颜色。

    private void initPaint(Context context, AttributeSet attrs) {
   
   
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);

        // 获取用户设置的颜色,若未设置则使用默认颜色
        int initialColor = typedArray.getColor(R.styleable.ColorTrackTextView_originColor, getTextColors().getDefaultColor());
        int changedColor = typedArray.getColor(R.styleable.ColorTrackTextView_changeColor, getTextColors().getDefaultColor(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值