android - 使用掩码显示具有 2 种不同颜色的 TextView

标签 android android-view android-custom-view porter-duff android-paint

我正在尝试实现与此类似的效果:

enter image description here

我现在在做什么:

public MaskedTextView(Context context, AttributeSet attrs) {
    super(context, attrs);

    p = new Paint(Paint.ANTI_ALIAS_FLAG);
    p.setTextSize(25);
    p.setColor(Color.GREEN);

    pReplace = new Paint(p);
    pReplace.setColor(Color.BLUE);
    pReplace.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));

    pMask = new Paint();
    int lightGradientColor = getResources().getColor(R.color.dailyGoalLowLight);
    int darkGradientColor = getResources().getColor(R.color.dailyGoalLowDark);
    Shader shader = new LinearGradient(0, 0, 150, 0, lightGradientColor, darkGradientColor, Shader.TileMode.CLAMP);
    pMask.setShader(shader);
    pMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.save();
    if (!Utils.isEmpty(sText)) {
        canvas.drawText(sText, 150, getHeight() / 2, p);
        canvas.drawRect(0, 0, 180, getHeight(), pMask);
        canvas.drawText(sText, 150, getHeight()/2, pReplace);
    }
    canvas.restore();
}

这导致:

enter image description here

关闭,这里的问题是设置pMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));时水平线性渐变没有显示。

如果我注释掉该行,我会得到以下结果:

enter image description here

再次关闭,但现在线性渐变完全覆盖了文本。有人可以帮我解决我在这里缺少的东西吗?有没有更好的方法来达到这个效果?

最佳答案

PorterDuff.Mode.SRC_IN 可能有帮助。 并且 setLayerType(View.LAYER_TYPE_SOFTWARE, null); 应该被调用以与 SRC_IN 一起工作。

public class MaskedTextView extends View {

    private final Paint pLeftBg;
    private final Paint pText;
    private final Paint pRightMask;
    private String mText = "web";

    public MaskedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        pLeftBg = new Paint();
        int lightGradientColor = ContextCompat.getColor(getContext(), R.color.dailyGoalLowLight);
        int darkGradientColor = ContextCompat.getColor(getContext(), R.color.dailyGoalLowDark);
        Shader shader = new LinearGradient(0, 0, 150, 0, lightGradientColor, darkGradientColor, Shader.TileMode.CLAMP);
        pLeftBg.setShader(shader);

        pText = new Paint(Paint.ANTI_ALIAS_FLAG);
        pText.setTextSize(50);
        pText.setColor(Color.WHITE);

        pRightMask = new Paint();
        pRightMask.setColor(ContextCompat.getColor(getContext(), R.color.dailyGoalLowLight));
        pRightMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

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

        canvas.save();
        canvas.drawRect(0, 0, 100, getHeight(), pLeftBg);
        canvas.drawText(mText, 50, getHeight() / 2, pText);
        canvas.drawRect(100, 0, getWidth(), getHeight(), pRightMask);
        canvas.restore();
    }
}

输出:

enter image description here

关于android - 使用掩码显示具有 2 种不同颜色的 TextView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39713782/

相关文章:

android - 我需要在自定义 View 中回调 super.onDraw() 吗?

android - 使用 TextView 和 EditText 的自定义 View 不适用于 android :fastForward

java.lang.NoClassDefFoundError : Failed resolution of: Landroid/support/v4/graphics/ColorUtils;

java - 将 ListView 添加到 Fragment 时出错

android - E/FirebaseCrashlytics : Failed to retrieve settings from https://firebase-settings. crashlytics.com/spi/v2/platforms/android/gmp/XXXX/settings

android - fragment - 获取 View 在调用 onCreateView 时已经有父错误

java - 如何在 Android 上获取新的 Window 实例?

android - 使用上下文菜单在编辑器中插入文本和图片

android - 使用 View.BaseSavedState 覆盖 View.onSaveInstanceState() 和 View.onRestoreInstanceState()?

android - 自定义 View 仅在 XML 预览中未正确对齐