Android 如何将PorterDuff.Mode.MULTIPLY正确应用于onDraw()中可绘制的向量;

Android 如何将PorterDuff.Mode.MULTIPLY正确应用于onDraw()中可绘制的向量;,android,ondraw,android-vectordrawable,porter-duff,Android,Ondraw,Android Vectordrawable,Porter Duff,在自定义视图中的onDraw()方法中,我试图将一个矩形覆盖在一个向量可绘制对象的顶部。理想的效果是眼睛的顶部为紫色,底部保持灰色,背景保持深灰色。为了达到这个效果,我使用了PorterDuff.Mode.MULTIPLY 不幸的是,我实现的效果是不正确的(向量可绘制的背景受到影响,好像它没有将其识别为路径): 这是我的密码: public class EyeStatusIcon extends View { private Rect canvasRect = null; p

在自定义视图中的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的透明背景向量可绘制部分?
谢谢大家!

我通过为前景创建第二个画布,并裁剪绘制在其上的位图(上面写着
getHeight()/2
),找到了解决我自己问题的方法。希望这对别人有帮助。这可以用来创建一个很好的滑动courtain效果

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);
    }

}

非常感谢。当然,欢迎您将其作为替代解决方案发布。我想在java中这样做,以便能够通过编程更改效果的范围,并创建一种预加载程序。