問題說明:
一般在音視頻開發中,我們會使用SurfaceView進行視頻畫面的展示。當場景中有多個SurfaceView的時候,會出現展示內容的堆疊覆蓋,導致我們本想看到的內容被遮擋。
一、SurfaceView 簡介
SurfaceView是View的子類,它內嵌了一個專門用於繪制的Surface,你可以控制這個Surface的格式和尺寸,Surfaceview控制這個Surface的繪制位置。Surface是縱深排序(Z-ordered)的,說明它總在自己所在窗口的后面。SurfaceView提供了一個可見區域,只有在這個可見區域內的surface內容才可見。surface的排版顯示受到視圖層級關系的影響,它的兄弟視圖結點會在頂端顯示。這意味者 surface的內容會被它的兄弟視圖遮擋,這一特性可以用來放置遮蓋物(overlays)(例如,文本和按鈕等控件)。
二、解決方案
在SurfaceView onAttachedToWindow之前調用如下設置:
surfaceView.setZOrderMediaOverlay(true);
在onViewAttachedToWindow的時候,調用如下設置:
surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
三、核心API方法描述
1). public void setZOrderMediaOverla(boolean isMediaOverlay)
控制這個surfaceView是否被放在另一個普通的surfaceView上面(但是仍然在窗口之后)。這個函數通常被用來將覆蓋層至於一個多媒體層上面。
這個函數必須在窗口被添加到窗口管理器之前設置。
調用這個函數會使之前調用的setZOrderOnTop(boolean)無效。
Added in API level 5
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).
這個函數必須在窗口被添加到窗口管理器之前設置。
調用這個函數會使之前調用的setZOrderOnTop(boolean)無效。
2).surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
此設置的意義是將布局中不展示內容的地方設置為透明,這樣兩個SurfaceView的內容就能按照我們的需要進行展示了。