ViewOutlineProvider 轮廓裁剪(5.0 以上特性)
需求: 需要把相机预览SurfaceView裁剪成圆形,ViewOutlineProvider 很好的实现了这个效果
文章目录
关于ViewOutlineProvider
ViewOutlineProvider是抽象类,View构建其{@link Outline}的接口,用于阴影投射和剪切。
View 相关的方法
setOutlineProvider()
设置View的{@link ViewOutlineProvider},生成定义其投射的阴影形状的轮廓(Outline),并启用轮廓剪裁。
默认的轮廓为ViewOutlineProvider中的BACKGROUND,通过{@link Drawable#getOutline(Outline)}从View的背景drawable中查询轮廓(Outline).
如果ViewOutlineProvider为null,如果查询轮廓返回false,或者如果生成的Outline为空{@link Outline#isEmpty()},则不会投射阴影
只有Outline#canClip()返回true的轮廓才可用于裁剪
setClipToOutline()
设置是否应使用视图轮廓来剪切视图的内容
note: 如果View的Outline从{@link Outline#canClip()}返回true,则只会遵循此标志
代码
圆形:
surfaceView.setOutlineProvider(new CircleViewOutlineProvider(dp1));
surfaceView.setClipToOutline(true);
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static class CircleViewOutlineProvider extends ViewOutlineProvider {
public CircleViewOutlineProvider() {
}
@Override
public void getOutline(View view, Outline outline) {
//864,648 横屏情况下,宽>高
Log.d("Circle===","width:"+view.getWidth()+"==height:"+view.getHeight());
//裁剪成一个圆形
int left0 = (view.getWidth() - view.getHeight()) / 2;
int top0 = 0;
int right0 = left0 + view.getHeight() ;
int bottom0 = view.getHeight() ;
outline.setOval(left0, top0, right0, bottom0);
}
}
扩展
如果不想裁剪SurfaceView,也可以在SurfaceView 外嵌套FrameLayout,通过设置FrameLayout的ViewOutlineProvider 来达到目的,代码类似
圆角矩形:
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static class RoundViewOutlineProvider extends ViewOutlineProvider {
private float mRadius;
public RoundViewOutlineProvider(float radius) {
this.mRadius = radius;
}
@Override
public void getOutline(View view, Outline outline) {
Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
int leftMargin = 0;
int topMargin = 0;
Rect selfRect = new Rect(leftMargin, topMargin,
rect.right - rect.left - leftMargin,
rect.bottom - rect.top - topMargin);
// outline.setRoundRect(0, 0, view.width, view.height, mRadius)
outline.setRoundRect(selfRect, mRadius);
}
}
引用: