Android Camera2 API:相机预览SurfaceView绘矩形后黑屏问题排查
我来帮你排查下这个问题——你现在看不到相机预览只显示黑色背景,主要有几个关键原因,咱们一步步来修复:
1. 重复添加OverlayTextureView导致布局混乱
看你的Fragment代码,布局文件里已经定义了<com.example.OverlayTextureView android:id="@+id/overlay"/>,但你在onCreateView里又手动添加了一个新的OverlayTextureView实例到容器中。这会导致两个重叠的SurfaceView,新添加的那个会完全覆盖在TextureView上方,而且没有正确配置透明属性,直接显示黑色背景。
修复方案:
删掉onCreateView里手动添加View的代码:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view =inflater.inflate(R.layout.fragment_camera2_basic, container, false); mVwMainContainer = (RelativeLayout) view.findViewById(R.id.vwMainContainer); // 移除这行重复添加的代码 // mVwMainContainer.addView(new OverlayTextureView(getActivity())); return view; }
2. SurfaceView的透明与层级配置错误
SurfaceView的绘制Surface是独立于应用窗口的,默认是不透明的,即使你设置了PixelFormat.TRANSPARENT,如果不调整它的Z-order层级,依然会遮挡下面的TextureView。
修复方案:
在OverlayTextureView的构造函数中添加setZOrderOnTop(true),让它的Surface悬浮在所有View的最上层,同时保持透明:
public OverlayTextureView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mHolder = getHolder(); mHolder.setFormat(PixelFormat.TRANSPARENT); // 添加这行,让SurfaceView的Surface在顶层显示 setZOrderOnTop(true); this.context = context; paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); }
3. SurfaceView的绘制逻辑冗余冲突
你同时重写了onDraw方法(属于View的绘制流程)和使用SurfaceHolder的lockCanvas进行绘制,这会导致绘制逻辑冲突。SurfaceView的正确绘制方式应该依赖SurfaceHolder的回调,不需要重写onDraw。
优化方案:
移除onDraw方法和构造函数里的setWillNotDraw(false)(默认就是true,表示View本身不参与绘制,交给Surface处理):
// 删掉这个方法 // @Override // protected void onDraw(Canvas canvas) { // drawMyStuff(canvas); // } // 同时删掉构造函数里的这行 // setWillNotDraw(false);
4. 额外建议:确保相机预览正常启动
最后要确认你的TextureView已经正确绑定了相机预览逻辑(比如Camera2 API的会话配置),如果相机本身没有启动预览,即使SurfaceView配置正确,也只会看到黑色背景。
调整完以上几点后,你应该能看到相机预览,同时在上面绘制出绿色的矩形边框了。
内容的提问来源于stack exchange,提问作者jassy




