Search code examples
androidviewsinch

Sinch local camera view always stays on top


I have this view for display videos

<FrameLayout
    android:id="@+id/remoteViewLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/remote_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <RelativeLayout
        android:id="@+id/local_view"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_gravity="bottom|right" />
</FrameLayout>

Upon click on local_view, I need to remove views from both RelativeLayout and add again in them in different position. I am using flag to know the current loaded views.

private String loadedView = "1";

binding.contentSinchIncomingCall.localView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        if (videoController == null) {
            videoController = mSinchServiceInterface.getVideoController();
        }

        if (loadedView.equals("1")) {
            loadedView = "2";

            ((ViewGroup) videoController.getLocalView().getParent()).removeView(videoController.getLocalView());
            ((ViewGroup) videoController.getRemoteView().getParent()).removeView(videoController.getRemoteView());

            binding.contentSinchIncomingCall.remoteView.addView(videoController.getLocalView());
            binding.contentSinchIncomingCall.localView.addView(videoController.getRemoteView());

            binding.contentSinchIncomingCall.localView.requestLayout();
            binding.contentSinchIncomingCall.localView.invalidate();
            binding.contentSinchIncomingCall.remoteViewLayout.bringChildToFront(binding.contentSinchIncomingCall.localView);

        } else {
            loadedView = "1";

            ((ViewGroup) videoController.getLocalView().getParent()).removeView(videoController.getLocalView());
            ((ViewGroup) videoController.getRemoteView().getParent()).removeView(videoController.getRemoteView());

            binding.contentSinchIncomingCall.remoteView.addView(videoController.getRemoteView());
            binding.contentSinchIncomingCall.localView.addView(videoController.getLocalView());

            binding.contentSinchIncomingCall.localView.requestLayout();
            binding.contentSinchIncomingCall.localView.invalidate();
            binding.contentSinchIncomingCall.remoteViewLayout.bringChildToFront(binding.contentSinchIncomingCall.localView);

        }
    }
});

But after changing the positions, remote_view overlaps local_view. I am using bringChildToFront method to bring local_view to front but still not working. Please help me to resolve this issue.

Screenshots :- First loaded views

After click


Solution

  • Since both remote and local video are overlay surfaces, standard view hierarchy manipulation API like bringChildToFront will not work. Think of overlay view as a 'cut' rectangular hole in all layers above the video view, which makes overlay always 'onTop'. Obviously, there would be a conflict when two 'always on top' overlay views are overlapping. This has been addressed in Sinch Android SDK 3.13.0. Please use VideoController's setLocalVideoZOrder:

    Sets whether local video (preview from camera) should be rendered on top of remove video view (default behaviour) or vice versa in case views are overlapping. * @param onTopOfRemoteView if set to false will make remove video rendered on top of preview.

    void setLocalVideoZOrder(boolean onTopOfRemoteView);