Android:如何正确隐藏系统界面 [英] Android: How to hide the System UI properly

查看:269
本文介绍了Android:如何正确隐藏系统界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发视频播放器应用程序,但遇到了问题.我有一个自定义视频控制器,其中包含一个全屏按钮,当用户进入全屏模式时,我想隐藏系统UI(导航和状态栏).我试图做类似

当我单击全屏按钮时,我将方向更改为横向,并且隐藏了系统用户界面,但播放器无法全屏显示.看起来像下面的屏幕:

此外,当我点击屏幕时,我想显示我的视频控制器,但是系统UI却显示以下内容,

那么,我该如何实现这种行为?以下是我全屏显示和隐藏/显示系统用户界面的方法:

  @Override公共无效toggleTullscreen(){LinearLayout.LayoutParams参数=(LinearLayout.LayoutParams)mVideoContainer.getLayoutParams();如果(!mFullscreen){setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);hideSystemUI();DisplayMetrics指标= new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);params.width = metrics.widthPixels;params.height = metrics.heightPixels;params.setMargins(0,0,0,0);} 别的 {setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);showSystemUI();DisplayMetrics指标= new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);params.width = metrics.widthPixels;params.height =(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,300,指标);params.setMargins(0,0,0,0);}mVideoContainer.setLayoutParams(params);mFullscreen =!mFullscreen;}私人void hideSystemUI(){查看decorView = getWindow().getDecorView();int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;如果(Build.VERSION.SDK_INT< 16){getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)} 别的 {uiOptions | = View.SYSTEM_UI_FLAG_FULLSCREEN;}decorView.setSystemUiVisibility(uiOptions);}私人无效showSystemUI(){查看decorView = getWindow().getDecorView();decorView.setSystemUiVisibility(0);} 

这是我的布局:

 <?xml version ="1.0" encoding ="utf-8"?>< LinearLayoutxmlns:android ="http://schemas.android.com/apk/res/android"android:id ="@ + id/video_container"android:layout_width ="match_parent"android:layout_height ="match_parent"android:orientation ="vertical">< FrameLayoutandroid:id ="@ + id/videoSurfaceContainer"android:layout_width ="match_parent"android:layout_height ="300dp">< SurfaceViewandroid:id ="@ + id/videoSurface"android:layout_width ="match_parent"android:layout_height ="match_parent"/></FrameLayout></LinearLayout> 

解决方案

我在要隐藏导航栏和状态栏的每个活动中都包含此内容:

  public void hideToolBr(){//BEGIN_INCLUDE(get_current_ui_flags)//当前启用的UI选项由一个位域表示.//getSystemUiVisibility()给我们该位域.int uiOptions = getWindow().getDecorView().getSystemUiVisibility();int newUiOptions = uiOptions;//END_INCLUDE(get_current_ui_flags)//BEGIN_INCLUDE(toggle_ui_flags)boolean isImmersiveModeEnabled =((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)== uiOptions);如果(isImmersiveModeEnabled){Log.i(Constants.TAG_DEF,关闭沉浸式模式.");} 别的 {Log.i(Constants.TAG_DEF,打开沉浸模式模式.");}//隐藏导航栏:向后兼容ICS.如果(Build.VERSION.SDK_INT> = 14){newUiOptions ^ = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;}//隐藏状态栏:向后兼容Jellybean如果(Build.VERSION.SDK_INT> = 16){newUiOptions ^ = View.SYSTEM_UI_FLAG_FULLSCREEN;}//身临其境的模式:向后兼容KitKat.//注意,此标志本身不会做任何事情,只会增加行为//为HIDE_NAVIGATION和FLAG_FULLSCREEN.就本样本而言//所有三个标志都一起切换.//请注意,有两个浸入模式的UI标志,其中之一称为粘滞".//粘性沉浸模式的不同之处在于,它使导航栏和状态栏//半透明,并且当用户与之交互时,UI标志不会被清除//屏幕.如果(Build.VERSION.SDK_INT> = 18){newUiOptions ^ = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;}getWindow().getDecorView().setSystemUiVisibility(newUiOptions);//END_INCLUDE(set_ui_flags)} 

然后在我活动的onCreate方法中,我在 setContentView()

之后调用它

  hideToolBr(); 

然后,用户所需要做的就是从底部向上滑动或从顶部向下滑动以调出状态栏或导航栏.Google将其称为沉浸模式".它使开发人员可以充分利用设备的屏幕空间.

来自Google的沉浸模式示例,称其为系统UI:

 //此代码段显示系统栏.它通过删除所有标志来做到这一点//使内容显示在系统栏下方的内容除外.私人无效showSystemUI(){mDecorView.setSystemUiVisibility(查看.SYSTEM_UI_FLAG_LAYOUT_STABLE|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);} 

您可以在此处找到更多信息.

也将此添加到您的styles.xml

 < style name ="YourTheme.NoActionBar">< item name ="windowActionBar"> false</item>< item name ="windowNoTitle"> true</item>< item name ="android:colorForeground"> @ color/colorPrimaryDark</item></style> 

I'm developing a video player application and I've faced to a problem. I have a custom video controller which contains a fullscreen button and I want hide the System UI (navigation and status bars) when the user enters to fullscreen mode. I've tried to do something like this, but it doesn't work properly. My application is like the screenshot below:

When I click the fullscreen button, I change orientation to landscape and I hide the System UI, but my player doesn't get fullscreen. It looks like the screen below:

Also, when I tap the screen I want to show my video controller, but the System UI shows the below content, instead:

So, how can I implement this behavior? Below are my methods for fullscreen and hiding/showing the System UI:

@Override
public void toggleFullscreen() {
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mVideoContainer.getLayoutParams();
    if (!mFullscreen) {
             setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        hideSystemUI();
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        params.width = metrics.widthPixels;
        params.height = metrics.heightPixels;
        params.setMargins(0, 0, 0, 0);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        showSystemUI();
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        params.width = metrics.widthPixels;
        params.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, metrics);
            params.setMargins(0, 0, 0, 0);
    }
    mVideoContainer.setLayoutParams(params);
    mFullscreen = !mFullscreen;
}

private void hideSystemUI() {
    View decorView = getWindow().getDecorView();
    int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    if (Build.VERSION.SDK_INT < 16) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN)
    } else {
        uiOptions |= View.SYSTEM_UI_FLAG_FULLSCREEN;
    }
    decorView.setSystemUiVisibility(uiOptions);
}

private void showSystemUI() {
    View decorView = getWindow().getDecorView();
    decorView.setSystemUiVisibility(0);
}

Here's my layout:

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

    <FrameLayout
        android:id="@+id/videoSurfaceContainer"
        android:layout_width="match_parent"
        android:layout_height="300dp" >

        <SurfaceView
            android:id="@+id/videoSurface"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>
</LinearLayout>

解决方案

I include this in every activity that I want to hide the nav bar and status bar:

    public void hideToolBr(){

        // BEGIN_INCLUDE (get_current_ui_flags)
        // The UI options currently enabled are represented by a bitfield.
        // getSystemUiVisibility() gives us that bitfield.
        int uiOptions = getWindow().getDecorView().getSystemUiVisibility();
        int newUiOptions = uiOptions;
        // END_INCLUDE (get_current_ui_flags)
        // BEGIN_INCLUDE (toggle_ui_flags)
        boolean isImmersiveModeEnabled =
                ((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
        if (isImmersiveModeEnabled) {
            Log.i(Constants.TAG_DEF, "Turning immersive mode mode off. ");
        } else {
            Log.i(Constants.TAG_DEF, "Turning immersive mode mode on.");
        }

        // Navigation bar hiding:  Backwards compatible to ICS.
        if (Build.VERSION.SDK_INT >= 14) {
            newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
        }

        // Status bar hiding: Backwards compatible to Jellybean
        if (Build.VERSION.SDK_INT >= 16) {
            newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
        }

        // Immersive mode: Backward compatible to KitKat.
        // Note that this flag doesn't do anything by itself, it only augments the behavior
        // of HIDE_NAVIGATION and FLAG_FULLSCREEN.  For the purposes of this sample
        // all three flags are being toggled together.
        // Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
        // Sticky immersive mode differs in that it makes the navigation and status bars
        // semi-transparent, and the UI flag does not get cleared when the user interacts with
        // the screen.
        if (Build.VERSION.SDK_INT >= 18) {
            newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        }

        getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
        //END_INCLUDE (set_ui_flags)

    }

Then in my activity's onCreate method, I call this after setContentView()

hideToolBr();

Then all the user has to do is swipe up from the bottom or swipe down from the top to bring up the status bar or nav bar. Google calls this "immersive mode". It gives the developer full use of the devices' screen real-estate.

Taken from Googles example of immersive mode, calling this shows the system UI:

    // This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

You can find more information here.

Edit:

Add this to your styles.xml as well

    <style name="YourTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:colorForeground">@color/colorPrimaryDark</item>
</style>

这篇关于Android:如何正确隐藏系统界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆