Open ZDZN opened 5 years ago
I modified your code to achieve my effect as the code below, but I still hope your library can support using SurfaceView inside ShapeOfView.
public class MaskLayout extends FrameLayout {
private Paint mTransparentPaint;
private Paint mDrawPaint;
private MaskManager mMaskManager;
private boolean mRequireUpdate;
public MaskLayout(@NonNull Context context) {
this(context, null, 0);
}
public MaskLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MaskLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mTransparentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mDrawPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mDrawPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mDrawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mDrawPaint.setStrokeWidth(1);
mRequireUpdate = true;
mMaskManager = new MaskManager();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
requireUpdate();
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
if(null == mMaskManager) {
super.dispatchDraw(canvas);
return;
}
int width = getWidth() - getPaddingLeft() - getPaddingRight();
int height = getHeight() - getPaddingTop() - getPaddingBottom();
if(mRequireUpdate) {
mMaskManager.setupMask(width, height);
//this needs to be fixed for 25.4.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && ViewCompat.getElevation(this) > 0f) {
try {
setOutlineProvider(getOutlineProvider());
} catch (Exception e) {
e.printStackTrace();
}
}
postInvalidate();
mRequireUpdate = false;
}
canvas.drawPath(mMaskManager.getMask(), mTransparentPaint);
canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
canvas.drawPath(mMaskManager.getMask(), mDrawPaint);
canvas.restore();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public ViewOutlineProvider getOutlineProvider() {
return new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
if (mMaskManager != null && !isInEditMode()) {
final Path shadowConvexPath = mMaskManager.getShadow();
if (shadowConvexPath != null) {
try {
outline.setConvexPath(shadowConvexPath);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
}
public void setMakCreator(MaskManager.MaskCreator creator) {
mMaskManager.setMaskCreator(creator);
requireUpdate();
}
private void requireUpdate() {
mRequireUpdate = true;
postInvalidate();
}
}
what did you change to make it work ? So I can add it inside ShapeOfView
Le lun. 28 janv. 2019 à 03:24, ZDZN notifications@github.com a écrit :
I modified your code to achieve my effect as the code below, but I still hope your library can support using SurfaceView inside ShapeOfView.
public class MaskLayout extends FrameLayout {
private Paint mTransparentPaint; private Paint mDrawPaint; private MaskManager mMaskManager; private boolean mRequireUpdate; public MaskLayout(@NonNull Context context) { this(context, null, 0); } public MaskLayout(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public MaskLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mTransparentPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mDrawPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mDrawPaint.setStyle(Paint.Style.FILL_AND_STROKE); mDrawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mDrawPaint.setStrokeWidth(1); mRequireUpdate = true; mMaskManager = new MaskManager(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (changed) { requireUpdate(); } } @Override protected void dispatchDraw(Canvas canvas) { if(null == mMaskManager) { super.dispatchDraw(canvas); return; } int width = getWidth() - getPaddingLeft() - getPaddingRight(); int height = getHeight() - getPaddingTop() - getPaddingBottom(); if(mRequireUpdate) { mMaskManager.setupMask(width, height); //this needs to be fixed for 25.4.0 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && ViewCompat.getElevation(this) > 0f) { try { setOutlineProvider(getOutlineProvider()); } catch (Exception e) { e.printStackTrace(); } } postInvalidate(); mRequireUpdate = false; } canvas.drawPath(mMaskManager.getMask(), mTransparentPaint); canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG); super.dispatchDraw(canvas); canvas.drawPath(mMaskManager.getMask(), mDrawPaint); canvas.restore(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public ViewOutlineProvider getOutlineProvider() { return new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { if (mMaskManager != null && !isInEditMode()) { final Path shadowConvexPath = mMaskManager.getShadow(); if (shadowConvexPath != null) { try { outline.setConvexPath(shadowConvexPath); } catch (Exception e) { e.printStackTrace(); } } } } }; } public void setMakCreator(MaskManager.MaskCreator creator) { mMaskManager.setMaskCreator(creator); requireUpdate(); } private void requireUpdate() { mRequireUpdate = true; postInvalidate(); }
}
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/florent37/ShapeOfView/issues/47#issuecomment-457980222, or mute the thread https://github.com/notifications/unsubscribe-auth/AFfQXAITQEw5sVw30t_vIVywK8rykNQaks5vHl9HgaJpZM4aQUV0 .
@florent37 I draw a hole for SurfaceView by using PorterDuff.Mode.CLEAR before I call super.dispatchDraw(canvas). I am not familiar with the effect about changing layer type, so I use saveLayer instead of setLayerType. ShapeOfView use different parameters for setLayerType and drawPath in order to be compatible with different version, but my codes only tested in my phone and may not be compatible with your view.
The main change as the code below:
canvas.drawPath(mMaskManager.getMask(), mTransparentPaint); // draw a hole for SurfaceView
canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG); // save a layer to draw child
super.dispatchDraw(canvas); // draw child
canvas.drawPath(mMaskManager.getMask(), mDrawPaint); // clip shape
canvas.restore();
I wanted to show camera preview in a circle view, so I tried to put a SurfaceView inside CircleView. But the SurfaceView seemed to be covered by CircleView and showed nothing. If I change the CircleView to FrameLayout, SurfaceView can show camera preview in a rect. Can you give me some advice to solve this ?Thank you.