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

问题描述 投票:0回答:1

在我的自定义视图中的onDraw()方法中,我试图将矩形覆盖在矢量可绘制对象的顶部。理想的效果是使眼睛的顶部为紫罗兰色,底部为灰色,而背景为深灰色。为了达到这种效果,我使用了PorterDuff.Mode.MULTIPLY。

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

Example of overlaying a Rect over a VectorDrawable

这是我的代码:

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的一部分?谢谢!

android ondraw android-vectordrawable porter-duff
1个回答
0
投票

我通过为前景创建第二个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);
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.