I am trying to achieve an effect like this:

What am I doing now:
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(); }
This leads to:

Close, the problem is that the horizontal linear gradient is not displayed when setting pMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); .
If I comment on this line, I get the following result:

Close again, but now the linear gradient completely covers the text. Can someone help me with what I am missing here. Is there a better way to achieve this effect?
source share