Android中显示,隐藏Status Bar和Navigation Bar,沉浸式体验

随着Android版本的迭代更新,如何使某项特性能够兼容各个版本,一直困扰开发人员。比如状态栏(Status Bar)的显示与隐藏,本篇文章也主要讨论Android中状态栏(Status Bar)以及导航栏(Navigation Bar)的显示与隐藏。

1.在Android4.0及以下隐藏Status Bar

在Android4.0(API level 14)及以下你可以通过设置 WindowManager 的标志来隐藏Status Bar,你可以通过在代码中设置或者通过在manifest中设置activity的主题来实现。如果在你的APP中Status Bar需要一直隐藏,那么最好的方法是在manifest中设置activity或者application的主题。


    ...

当然,你也可以在代码中设置 WindowManager 的标志来实现。这种方式使得当程序需要根据用户的交互来显示或者隐藏Status Bar变得很容易。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // If the Android version is lower than Jellybean, use this call to hide
        // the status bar.
        if (Build.VERSION.SDK_INT < 16) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
        setContentView(R.layout.activity_main);
    }
    ...
}


当你设置了WindowManager 的标志时,它会一直起作用,除非你清除这些标志。

那么问题来了,当我们因为需要隐藏Status Bar而激活FLAG_FULLSCREEN标志时,如果来清除此标记使得Status Bar重新显示出来。这个时候我们可以通过设置  FLAG_LAYOUT_IN_SCREEN  标记来使Status Bar重新显示,这也避免了你的布局在Status Bar显示或隐藏时需要重新调整大小。

2.在Android4.1(API level 16) 及以上隐藏Status Bar

在Android4.1(API level 16) 及以上隐藏Status Bar可以调用 setSystemUiVisibility()方法,该方法在一个独特的视图水平设置UI的标记,这些设置会聚集到window层级,相比设置WindowManager 的标记,使用这个方法可以让你对Status Bar有更细粒度的控制。

View decorView = getWindow().getDecorView();
// Hide the status bar.
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
// Remember that you should never show the action bar if the
// status bar is hidden, so hide that too if necessary.
ActionBar actionBar = getActionBar();
actionBar.hide();
注意:

1.一旦UI标记被清除(比如离开当前activity),如果你想继续隐藏Status Bar,你需要重新设置他们。

2.在哪个位置设置UI标记很重要。如果你在 onCreate()  方法中设置,当用户点击home键时,此时Status Bar会出现,当用户再次打开该activity时,  onCreate() 方法不会被调用,导致Status Bar会一直显示。如果你想在用户导航到当前activity或者导航出当前activity时一直保持系统UI的改变,你应该在 onResume() 或者 onWindowFocusChanged().中设置UI标记。

3.当你离开当前视图时,通过该方法设置的UI标记会被清除。

3.使内容出现在Status Bar的后面(在Android 4.1及以上 

Android 4.1 及以上你可以设置你的应用程序的内容显示在Status Bar的后面,这样一来,当Status Bar显示或者隐藏时,你的内容不仅就不需要重新调整大小了。要达到这样的效果使用 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN标记。你可能同时需要使用 SYSTEM_UI_FLAG_LAYOUT_STABLE来帮助你的app持有一个稳定的布局。

在大多数情况下,你可以通过在你的布局xml文件中添加一个标记android:fitsSystemWindows ,并设置为true,这会导致系统窗口的父布局调整为系统窗口留的padding。这种方式对大多数app有效。

然而,在某些情况下,你需要更改默认的padding,来直接操作你的布局相对于system bars如何放置,通过覆写fitSystemWindows(Rect insets)方法。

4.Dim the Status and Navigation Bars

你可以使用 SYSTEM_UI_FLAG_LOW_PROFILE 标记来dim Status and Navigation Bars,如下:

// This example uses decor view, but you can use any visible view.
View decorView = getActivity().getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView.setSystemUiVisibility(uiOptions);

通过这种方式,当用户触摸Status 和 Navigation Bars的区域时,会导致清除掉这个标记,一旦清除,如果你想继续dim  Status 和 Navigation Bars,你需要重新设置它。

5.显示Status and Navigation Bars

如果你想在代码里清除所有使用setSystemUiVisibility()方法设置的标记,可以按照如下方式:

View decorView = getActivity().getWindow().getDecorView();
// Calling setSystemUiVisibility() with a value of 0 clears
// all flags.
decorView.setSystemUiVisibility(0);

6.隐藏导航栏(Hiding the Navigation Bar

隐藏导航栏(Android 4.0 (API level 14))及以上引入,可以使用 SYSTEM_UI_FLAG_HIDE_NAVIGATION 标记来隐藏导航栏,如下代码:

View decorView = getWindow().getDecorView();
// 同时隐藏 navigation bar 和 status bar.
// SYSTEM_UI_FLAG_FULLSCREEN 标记仅仅存在于 Android 4.1 及以上, 但是当你隐藏navigation bar时也应该隐藏status bar
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
              | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);

注意:

1.通过这种方式,触摸屏幕的任何地方都会导致navigation bar (and status bar) 出现并且一直显示,用户的交互使得标记被清除。

2.一旦标记被清除,需要重新设置。

3.在哪个位置设置UI标记很重要。如果你在  onCreate()  方法中设置,当用户点击home键时,此时Status Bar会出现,当用户再次打开该activity时,  onCreate() 方法不会被调用,导致Status Bar会一直显示。如果你想在用户导航到当前activity或者导航出当前activity时一直保持系统UI的改变,你应该在 onResume() 或者 onWindowFocusChanged().中设置UI标记。

4.当你离开当前视图时,通过该方法设置的UI标记会被清除。

7.使程序的内容出现在导航栏(Navigation Bar)的后面

Android 4.1 及以上你可以设置你的应用程序的内容显示在Navigation Bar的后面,这样一来,当Navigation Bar显示或者隐藏时,你的内容不仅就不需要重新调整大小了。要达到这样的效果使用  SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION标记。你可能同时需要使用  SYSTEM_UI_FLAG_LAYOUT_STABLE帮助你的app持有一个稳定的布局。

8.使用沉浸式的全屏模式

在Android 4.4 (API Level 19)为setSystemUiVisibility() 引进了一个新的标记 SYSTEM_UI_FLAG_IMMERSIVE,来使你的app真正的全屏。当这个标记与SYSTEM_UI_FLAG_HIDE_NAVIGATION 和 SYSTEM_UI_FLAG_FULLSCREEN结合使用,隐藏 navigation 和 status bars并且让你的app能够捕获屏幕上的所有触摸事件。

当沉浸式全屏模式启用,你的activity任然可以接收所有的触摸事件。用户可以在system bars本来在的位置向内滑动从而使system bars显示出来。当然这会导致标记 SYSTEM_UI_FLAG_HIDE_NAVIGATION (如果设置了SYSTEM_UI_FLAG_FULLSCREEN也会被清除)会被清除。如果设置了监听器 View.OnSystemUiVisibilityChangeListener,此时会触发这个监听器。当然,如果你想让system bars 隔一会后自动隐藏,你应该使用SYSTEM_UI_FLAG_IMMERSIVE_STICKY 标记。注意,该标记不会触发任何监听器。

9.使用非粘性沉浸式

// This snippet hides the system bars.
private void hideSystemUI() {
    // Set the IMMERSIVE flag.
    // Set the content to appear under the system bars so that the content
    // doesn't resize when the system bars hide and show.
    mDecorView.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);
}

// 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);
}


10.使用粘性沉浸式

@Override
public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        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
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}

11.监听系统UI变化

要监听系统UI的变化,需要注册监听器,如下所示:

View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
        (new View.OnSystemUiVisibilityChangeListener() {
    @Override
    public void onSystemUiVisibilityChange(int visibility) {
        // Note that system bars will only be "visible" if none of the
        // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
            // TODO: The system bars are visible. Make any desired
            // adjustments to your UI, such as showing the action bar or
            // other navigational controls.
        } else {
            // TODO: The system bars are NOT visible. Make any desired
            // adjustments to your UI, such as hiding the action bar or
            // other navigational controls.
        }
    }
});






你可能感兴趣的:(Android,android,status,bar,Navigation,Bar)