Android videoview - immersive - overlapping controllers
Asked Answered
P

3

7

I have a videoview on my app and Im using gogole as a reference to make the video player full screen:

https://developer.android.com/training/system-ui/immersive#java

I was following the instruccion from the above website and i was able to make the videoplayer full screen but I gt a weird problem with my media controller and the device controller(they overlp) and don't know how to fixed any ideas what is the problem.

enter image description here

public class VideoPlayer extends AppCompatActivity {

    VideoView videoView;
    MediaController mediaController;
    private String TAG = VideoPlayer.class.getSimpleName();
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_player_activity);

        videoView = (VideoView) findViewById(R.id.videoView);
        mediaController = new MediaController(this);
        videoView.setVideoPath("android.resource://" + getPackageName() + "/" + R.raw.video1);
        mediaController.setAnchorView(videoView);
        videoView.setMediaController(mediaController);
        videoView.start(); 

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideSystemUI();
        }
    }

    private void hideSystemUI() { 
        View decorView = getWindow().getDecorView();
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
    } 
    private void showSystemUI() {
        Log.e(TAG, "111");
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }
}
Pillion answered 24/5, 2019 at 23:25 Comment(0)
V
1

Here is the fix for you. You have to update your controls margin dynamically by code. Idea is that add one overlay with controls in your layout file. and when navigation bar is visible update your controls bottom margin to push them up in screen. Rest code explains it worked for me.

Layout File : video_player_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    <VideoView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/videoView"/>

    <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content"
              android:text="Video Controls" android:textStyle="bold" android:textSize="40sp"
              android:textColor="#FFF"
              android:background="#444444"
              android:gravity="center"
              android:layout_alignParentBottom="true"/>

    <View android:visibility="gone" android:layout_width="match_parent" android:layout_height="match_parent"
          android:id="@+id/overlay"/>

</RelativeLayout> 

VideoPlayer.java

package com.vpiitsolution.stack;

import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;

public class VideoPlayer extends AppCompatActivity {

    VideoView videoView;
    MediaController mediaController;
    private String TAG = VideoPlayer.class.getSimpleName();
    private View overlay;

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_player_activity);

        videoView = findViewById(R.id.videoView);
        mediaController = new MediaController(this);
        //videoView.setVideoPath("android.resource://" + getPackageName() + "/" + R.raw.video1);
        mediaController.setAnchorView(videoView);
        videoView.setMediaController(mediaController);
        videoView.start();
        hideSystemUI();
        overlay = findViewById(R.id.overlay);
        overlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hideSystemUI();
            }
        });
        videoView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
                    updateControls(getNavigationBarHeight());
                    overlay.setVisibility(View.VISIBLE);
                } else {
                    updateControls(0);
                    overlay.setVisibility(View.GONE);
                }

            }
        });

    }

    int getNavigationBarHeight() {
        Resources resources = getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return resources.getDimensionPixelSize(resourceId);
        }
        return 0;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideSystemUI();
        } else {
            showSystemUI();
        }

    }

    private void hideSystemUI() {
        View decorView = getWindow().getDecorView();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                            | SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                            | View.SYSTEM_UI_FLAG_IMMERSIVE);
        }
    }

    void updateControls(int bottomMargin) {
        TextView tv = findViewById(R.id.text);
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) tv.getLayoutParams();
        params.bottomMargin = bottomMargin;
        tv.setLayoutParams(params);
    }

   /* private void hideSystemUI() {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_IMMERSIVE
                        // Set the content to appear under the system bars so that the
                        // content doesn't resize when the system bars hide and show.
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        // Hide the nav bar and status bar
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN);
    }*/

    private void showSystemUI() {
        Log.e(TAG, "111");
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

    }
}
Vespers answered 4/6, 2019 at 8:59 Comment(1)
Thanks for you helpPillion
P
3

You can use google exoplayer custom layout.You can add your custom layout by design a custom layout.It is very easy and it is provided by google exoplayer library.Please see the example link below: https://exoplayer.dev/ui-components.html

Punctuate answered 3/6, 2019 at 10:18 Comment(1)
Thank you this is a great optionPillion
V
1

Here is the fix for you. You have to update your controls margin dynamically by code. Idea is that add one overlay with controls in your layout file. and when navigation bar is visible update your controls bottom margin to push them up in screen. Rest code explains it worked for me.

Layout File : video_player_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    <VideoView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/videoView"/>

    <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content"
              android:text="Video Controls" android:textStyle="bold" android:textSize="40sp"
              android:textColor="#FFF"
              android:background="#444444"
              android:gravity="center"
              android:layout_alignParentBottom="true"/>

    <View android:visibility="gone" android:layout_width="match_parent" android:layout_height="match_parent"
          android:id="@+id/overlay"/>

</RelativeLayout> 

VideoPlayer.java

package com.vpiitsolution.stack;

import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;

public class VideoPlayer extends AppCompatActivity {

    VideoView videoView;
    MediaController mediaController;
    private String TAG = VideoPlayer.class.getSimpleName();
    private View overlay;

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_player_activity);

        videoView = findViewById(R.id.videoView);
        mediaController = new MediaController(this);
        //videoView.setVideoPath("android.resource://" + getPackageName() + "/" + R.raw.video1);
        mediaController.setAnchorView(videoView);
        videoView.setMediaController(mediaController);
        videoView.start();
        hideSystemUI();
        overlay = findViewById(R.id.overlay);
        overlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hideSystemUI();
            }
        });
        videoView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
                    updateControls(getNavigationBarHeight());
                    overlay.setVisibility(View.VISIBLE);
                } else {
                    updateControls(0);
                    overlay.setVisibility(View.GONE);
                }

            }
        });

    }

    int getNavigationBarHeight() {
        Resources resources = getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return resources.getDimensionPixelSize(resourceId);
        }
        return 0;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideSystemUI();
        } else {
            showSystemUI();
        }

    }

    private void hideSystemUI() {
        View decorView = getWindow().getDecorView();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                            | SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                            | View.SYSTEM_UI_FLAG_IMMERSIVE);
        }
    }

    void updateControls(int bottomMargin) {
        TextView tv = findViewById(R.id.text);
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) tv.getLayoutParams();
        params.bottomMargin = bottomMargin;
        tv.setLayoutParams(params);
    }

   /* private void hideSystemUI() {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_IMMERSIVE
                        // Set the content to appear under the system bars so that the
                        // content doesn't resize when the system bars hide and show.
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        // Hide the nav bar and status bar
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN);
    }*/

    private void showSystemUI() {
        Log.e(TAG, "111");
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

    }
}
Vespers answered 4/6, 2019 at 8:59 Comment(1)
Thanks for you helpPillion
A
0

I think the following might be happening:

From https://developer.android.com/training/system-ui/immersive#EnableFullscreen

Note: When you use the SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag, a swipe causes the system UI > to temporarily appear in a semi-transparent state, but no flags are cleared and your system UI visibility change listeners are not triggered.

From https://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_IMMERSIVE_STICKY

When system bars are hidden in immersive mode, they can be revealed temporarily with system gestures, such as swiping from the top of the screen. These transient system bars will overlay app’s content, may have some degree of transparency, and will automatically hide after a short timeout.

From https://developer.android.com/training/system-ui/immersive#leanback

The lean back mode is for fullscreen experiences in which users won't be interacting heavily with the screen, such as while watching a video.

When users want to bring back the system bars, they simply tap the screen anywhere.

To enable lean back mode, call setSystemUiVisibility() and pass SYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION.

Based on the preceding information I think removing the SYSTEM_UI_FLAG_IMMERSIVE_STICKY might help. I have not actually tried using this code but I hope this information helped.

Arciniega answered 30/5, 2019 at 0:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.