我想在一个圆形内呈现相机预览,就像这样:
我已经将其工作在添加到活动中的片段内。但是我希望通过将其添加到WindowManager中,在其他应用程序上方显示视图。
所以我已经能够在其他应用程序上方显示视图,但SurfaceView没有剪裁。另外,我已经将SurfaceView剪裁为圆形,但是在片段中。
我已经阅读了许多有关此主题的答案和文章。关于剪切SurfaceView的信息很少,并且没有符合我的要求的库。我找到的大部分信息只是解释如何将其剪裁为正方形或其他矩形。
添加到WindowManager后的效果
我正在尝试绘制
如何剪裁显示在所有视图上方的SurfaceView?
SurfaceView子类
public class CircleSurface extends SurfaceView {
private Path clipPath;
public CircleSurface(Context context) {
super(context);
init();
}
public CircleSurface(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleSurface(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setZOrderMediaOverlay(true);
setWillNotDraw(false);
SurfaceHolder sfhTrackHolder = getHolder();
sfhTrackHolder.setFormat(PixelFormat.TRANSPARENT);
clipPath = new Path();
//TODO: define the circle you actually want
clipPath.addCircle(710, 330, 250, Path.Direction.CW);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.clipPath(clipPath);
super.dispatchDraw(canvas);
}
}
为窗口管理器添加视图的服务
public class LiveStreamingService extends Service implements SurfaceHolder.Callback {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(startId, getNotification());
}
sharedInstance = this;
// android shouldn't auto restart this service
return START_NOT_STICKY;
}
@Override
public void onCreate() {
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
// camera view
CircleSurface cameraSurfaceView = new CircleSurface(this);
cameraSurfaceView.getHolder().addCallback(this);
wm.addView(cameraSurfaceView, getLayoutParams(360, 270));
}
private WindowManager.LayoutParams getLayoutParams(int width, int height) {
int overlayType = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O
? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
: WindowManager.LayoutParams.TYPE_PHONE;
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
width,
height,
overlayType,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT
);
return layoutParams;
}
// ...
}
更新
似乎相机的渲染与dispatchDraw
方法有所不同。我可以在dispatchDraw
中进行任何操作,但相机仍然显示为矩形。
super.dispatchDraw(canvas)
,但相机仍然显示。 - Troy