PorterDuff遮罩留下不透明的黑色背景 [英] PorterDuff masking leaves opaque black background

查看:198
本文介绍了PorterDuff遮罩留下不透明的黑色背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用定义为九个补丁的遮罩遮罩FrameLayout.但是,尽管此补丁在旧版本(例如4.4.4)的5.0+上可以正常工作,但该补丁会留下不透明的黑色背景.除了在渲染到屏幕或还原到软件层之前绘制到屏幕外的位图之外,还有什么方法可以避免这种情况?

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

推荐答案

尝试一下:

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

这篇关于PorterDuff遮罩留下不透明的黑色背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆