PorterDuff 掩蔽留下不透明的黑色背景
PorterDuff masking leaves opaque black background
我正在尝试使用定义为九个补丁的遮罩来遮盖 FrameLayout。然而,尽管它在 5.0+ 的旧版本(例如 4.4.4)上运行良好,但补丁会留下不透明的黑色背景。除了在渲染到屏幕或恢复到软件层之前绘制到屏幕外位图之外,还有什么可以避免这种情况吗?
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();
}
}
我正在尝试使用定义为九个补丁的遮罩来遮盖 FrameLayout。然而,尽管它在 5.0+ 的旧版本(例如 4.4.4)上运行良好,但补丁会留下不透明的黑色背景。除了在渲染到屏幕或恢复到软件层之前绘制到屏幕外位图之外,还有什么可以避免这种情况吗?
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();
}
}