Android两个Surface重叠显示

项目需求,相机预览做背景surfaceView1,播放其VideoView在其上,即:1个surfaceview获取相机预览数据作为背景(CustomCameraView),1个surfaceview在前一surfaceview之上作为绘图层(GamePanelView)。
布局使用framelayout,大小一致。由于surfaceview本身为透明的,本人认为直接层叠2个surfaceview就行了。结果无论在绘图层怎样绘图,图形都不会出现。查阅资料找到了解决方案。

在绘图层surfaceview初始化时,设置以下2个参数:
//surfaceview透明
holder.setFormat(PixelFormat.TRANSPARENT);
//surfceview放置在顶层,即始终位于最上层
setZOrderOnTop(true);

videoView.getHolder().setFormat(PixelFormat.TRANSPARENT);
videoView.setZOrderOnTop(true);
VideoView本身就是SurfaceView+MediaPlayer

当场景中有多个SurfaceView的时候,上层的SurfaceView可能会被下层的遮挡,这个时候需要使用setZOrderOnTop(true)或者setZOrderMediaOverlay(true)来控制SurfaceView的显示层次。

Android SDK对两个函数的描述:

public void setZOrderOnTop (boolean onTop)

Control whether the surface view's surface is placed on top of its window. Normally it is placed behind the window, to allow it to (for the most part) appear to composite with the views in the hierarchy. By setting this, you cause it to be placed above the window. This means that none of the contents of the window this SurfaceView is in will be visible on top of its surface.

Note that this must be set before the surface view's containing window is attached to the window manager.

Calling this overrides any previous call to setZOrderMediaOverlay(boolean).

控制这个surfaceView是否被放在窗口顶层。通常,为了使它与绘图树整合,它被放在窗口之后。通过这个函数,你可以使SurfaceView被放在窗口顶层。这意味着它所在的窗口的其他内容都不可见。(注:可以设置surfaceView透明来使其他内容可见)

这个函数必须在窗口被添加到窗口管理器之前设置。
调用这个函数会使之前调用的setZOrderMediaOverlay(boolean)无效;

public void setZOrderMediaOverlay (boolean isMediaOverlay)

Control whether the surface view's surface is placed on top of another regular surface view in the window (but still behind the window itself). This is typically used to place overlays on top of an underlying media surface view.

Note that this must be set before the surface view's containing window is attached to the window manager.

Calling this overrides any previous call to setZOrderOnTop(boolean).

控制这个surfaceView是否被放在另一个普通的surfaceView上面(但是仍然在窗口之后)。这个函数通常被用来将覆盖层至于一个多媒体层上面。

这个函数必须在窗口被添加到窗口管理器之前设置。

调用这个函数会使之前调用的setZOrderOnTop(boolean)无效。
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Android屏幕上直接使用Surface显示内容,可以使用SurfaceView类。以下是一些简单的步骤: 1. 在布局文件中添加SurfaceView组件: ```xml <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 2. 在Activity类中获取SurfaceView并设置SurfaceHolder.Callback: ```java public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback { private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); surfaceView = findViewById(R.id.surfaceView); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); } // 实现SurfaceHolder.Callback接口的三个方法 @Override public void surfaceCreated(SurfaceHolder holder) { // Surface创建后立即回调,可以在这里开始绘制 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // Surface尺寸发生变化时回调,可以在这里重置绘制内容 } @Override public void surfaceDestroyed(SurfaceHolder holder) { // Surface销毁时回调,可以在这里释放资源 } } ``` 3. 在SurfaceHolder.Callback的方法中进行绘制操作: ```java @Override public void surfaceCreated(SurfaceHolder holder) { Canvas canvas = holder.lockCanvas(); // 获取Canvas对象 // 在Canvas上进行绘制操作 Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint); holder.unlockCanvasAndPost(canvas); // 提交绘制结果 } ``` 以上是一个简单的例子,实际应用中可能需要使用线程或异步任务来进行复杂的绘制操作,以避免在主线程中卡顿。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值