如何正确地将 PorterDuff.Mode.MULTIPLY 应用于 onDraw() 中的矢量可绘制对象;

How to correctly apply PorterDuff.Mode.MULTIPLY to a vector drawable in onDraw();

在我的自定义视图的 onDraw() 方法中,我试图在矢量可绘制对象上叠加一个矩形。期望的效果是眼睛的顶部为紫色,底部保持灰色,背景保持深灰色。为了达到这种效果,我使用了 PorterDuff.Mode.MULTIPLY.

不幸的是,我实现的效果不正确(矢量绘图的背景受到影响,好像它没有将其识别为路径):

这是我的代码:

public class EyeStatusIcon extends View {

    private Rect canvasRect = null;
    private Rect colorMask = null;
    private Drawable eyeIcon;
    private Paint maskPaint;

    public EyeStatusIcon(Context c){
        this(c,null);
    }

    public EyeStatusIcon(Context c, AttributeSet s) {
        super(c, s);

        eyeIcon = c.getDrawable(R.drawable.illustration_eye_open);

        maskPaint = new Paint();
        maskPaint.setStyle(Paint.Style.FILL);
        maskPaint.setColor(c.getColor(R.color.accent));

        maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));

    }

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

        eyeIcon.setBounds(canvasRect.left, canvasRect.top, canvasRect.right, canvasRect.bottom);
        eyeIcon.draw(canvas);
        canvas.drawRect(colorMask, maskPaint);


    }

    @Override
    protected void onSizeChanged(int newW, int newH, int oldW, int oldH) {
        canvasRect = new Rect(0, 0, newW, newH);
        colorMask = new Rect(0, 0, newW, newH/2);
        super.onSizeChanged(newW, newH, oldW, oldH);
    }
}

我的问题是,如何应用 PorterDuff 混合(或其他技术)来为基于 SVG 的透明背景 Vector Drawable 的一部分着色? 谢谢!

我通过为前景创建第二个 Canvas 并裁剪绘制在其上的位图(其中显示 getHeight()/2)找到了解决我自己问题的方法。希望这对某人有帮助。这可以用来创建一个漂亮的滑动庭院效果。

public class EyeStatusIcon extends View {

    private Rect canvasRect = null;
    private Drawable normalIcon, tintedIcon;

    private Canvas foregroundCanvas;
    private Bitmap foregroundBitmap;

    public EyeStatusIcon(Context c){
        this(c,null);
    }

    public EyeStatusIcon(Context c, AttributeSet s) {
        super(c, s);

        setLayerType(LAYER_TYPE_HARDWARE, null);

        normalIcon = c.getDrawable(R.drawable.illustration_eye_open);
        tintedIcon = c.getDrawable(R.drawable.illustration_eye_open);
        if(tintedIcon != null) tintedIcon.setTint(c.getColor(R.color.accent));

    }

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

        normalIcon.setBounds(canvasRect.left, canvasRect.top, canvasRect.right, canvasRect.bottom);
        tintedIcon.setBounds(canvasRect.left, canvasRect.top, canvasRect.right, canvasRect.bottom);

        normalIcon.draw(canvas);

        tintedIcon.draw(foregroundCanvas);
        canvas.drawBitmap(foregroundBitmap, 0, 0, null);

    }

    @Override
    protected void onSizeChanged(int newW, int newH, int oldW, int oldH) {
        canvasRect = new Rect(0, 0, newW, newH);

        foregroundBitmap = Bitmap.createBitmap(getWidth(), getHeight()/2, Bitmap.Config.ARGB_8888);
        foregroundBitmap.eraseColor(Color.TRANSPARENT);
        foregroundCanvas = new Canvas(foregroundBitmap);
        foregroundCanvas.drawColor(Color.argb(0, 0, 0, 0));

        super.onSizeChanged(newW, newH, oldW, oldH);
    }

}