PorterDuff masking leaves opaque black background

淺唱寂寞╮ 提交于 2020-01-01 19:20:55

问题


I'm trying to mask a FrameLayout with a mask defined as a nine patch. However, although it works fine on 5.0+ on older versions (such as 4.4.4), the patch leaves an opaque black background. Is there anything that can be done to avoid this other than drawing to an off screen bitmap before rendering to the screen or reverting to software layers?

public class MaskedLayout extends FrameLayout {

    private final static PorterDuffXfermode DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private NinePatchDrawable mMask;

    private boolean mShowTail = true;
    private boolean mReverseLayout;

    public ChatBubbleLayout(Context context) {
        this(context, null);
    }

    public ChatBubbleLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ChatBubbleLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWillNotDraw(false);
        setLayerType(LAYER_TYPE_HARDWARE, mPaint);

        mMask = createMask(R.drawable.mask);
    }

    private NinePatchDrawable createMask(@DrawableRes int res) {
        final Bitmap maskBitmap = BitmapFactory.decodeResource(getResources(), res);
        final NinePatch patch = new NinePatch(maskBitmap, maskBitmap.getNinePatchChunk(), "Mask");
        return new NinePatchDrawable(getResources(), patch);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        if (w != oldw || h != oldh) {
            mMask.setBounds(0, 0, w, h);
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        mMask.getPaint().setXfermode(DST_IN);
        mMask.draw(canvas);
    }
}

回答1:


try this:

public class MaskedLayout extends FrameLayout {

    private NinePatchDrawable mMask;

    public MaskedLayout(Context context) {
        this(context, null);
    }

    public MaskedLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MaskedLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mMask = (NinePatchDrawable) getResources().getDrawable(R.drawable.mask);
        mMask.getPaint().setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mMask.setBounds(0, 0, w, h);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
        super.dispatchDraw(canvas);
        mMask.draw(canvas);
        canvas.restore();
    }
}


来源:https://stackoverflow.com/questions/37624857/porterduff-masking-leaves-opaque-black-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!