androidwebrtcsurfaceviewz-orderapprtcdemo

How to change surfaceview's z-order runtime in android


Recently I studied webrtc in android.

I wanna click SurfaceView A to make it fullscreen and another SurfaceView B becomes small, or maybe click B. But I found it is hard to change the z-order of two different surfaceviews in runtime.

Here is my layout

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">

<org.webrtc.PercentFrameLayout
    android:id="@+id/remote_video_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <org.webrtc.SurfaceViewRenderer
        android:id="@+id/remote_video_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</org.webrtc.PercentFrameLayout>

<org.webrtc.PercentFrameLayout
    android:id="@+id/local_video_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <org.webrtc.SurfaceViewRenderer
        android:id="@+id/local_video_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:keepScreenOn="true" />

</org.webrtc.PercentFrameLayout>


PercentFrameLayout is a ViewGroup subclass to measure the percent of screen.
I have tried to use setZOrderMediaOverlay in runtime but it failed. I found the SDK says

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


So is it means that i can't change SurfaceView z-order in runtime? Or is there any way to hack it?

Sorry for my bad English.



Edit 1
Both SurfaceViewRender and PercentFrameLayout are from the library, SurfaceViewRender is SurfaceView subclass.


Solution

  • Finally, I tried many times and solved it by myself.

    First, I change SurfaceViewRender A and B to View.GONE, then remove A and B from parent layout, setZOrderMediaOverlay A false and B true or A true and B false. The left steps just reversed.

    Just look like the below.

        mLocalRender.setVisibility(View.GONE);
        mRemoteRender.setVisibility(View.GONE);
        mLocalRenderLayout.removeView(mLocalRender);
        mRemoteRenderLayout.removeView(mRemoteRender);
        mLocalRender.setZOrderMediaOverlay(mLocalPreview);
        mRemoteRender.setZOrderMediaOverlay(!mLocalPreview);
        mLocalRenderLayout.addView(mLocalRender, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mRemoteRenderLayout.addView(mRemoteRender, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mLocalRender.setVisibility(View.VISIBLE);
        mRemoteRender.setVisibility(View.VISIBLE);