Using Immersive Full-Screen Mode

Android 4.4 (API Level 19) introduces a newSYSTEM_UI_FLAG_IMMERSIVE flag for setSystemUiVisibility()that lets your app go truly "full screen." This flag, when combined with the SYSTEM_UI_FLAG_HIDE_NAVIGATION andSYSTEM_UI_FLAG_FULLSCREEN flags, hides the navigation and status bars and lets your app capture all touch events on the screen.

When immersive full-screen mode is enabled, your activity continues to receive all touch events. The user can reveal the system bars with an inward swipe along the region where the system bars normally appear. This clears theSYSTEM_UI_FLAG_HIDE_NAVIGATION flag (and theSYSTEM_UI_FLAG_FULLSCREEN flag, if applied) so the system bars become visible. This also triggers yourView.OnSystemUiVisibilityChangeListener, if set. However, if you'd like the system bars to automatically hide again after a few moments, you can instead use theSYSTEM_UI_FLAG_IMMERSIVE_STICKY flag. Note that the "sticky" version of the flag doesn't trigger any listeners, as system bars temporarily shown in this mode are in a transient state.

Figure 1 illustrates the different "immersive mode" states:

system bars

Figure 1. Immersive mode states.

In figure 1:

  1. Non-immersive mode—This is how the app appears before it enters immersive mode. It is also how the app appears if you use the IMMERSIVE flag, and the user swipes to display the system bars, thereby clearing theSYSTEM_UI_FLAG_HIDE_NAVIGATION and SYSTEM_UI_FLAG_FULLSCREEN flags. Once these flags are cleared, the system bars reappear and remain visible.

    Note that it's best practice to keep all UI controls in sync with the system bars, to minimize the number of states your screen can be in. This provides a more seamless user experience. So here all UI controls are displayed along with the status bars. Once the app enters immersive mode, the UI controls are hidden along with the system bars. To ensure that your UI visibility stays in sync with system bar visibility, make sure to provide an appropriate View.OnSystemUiVisibilityChangeListener to watch for changes, as described inResponding to UI Visibility Changes.

  2. Reminder bubble—The system displays a reminder bubble the first time users enter immersive mode in your app. The reminder bubble reminds users how to display the system bars.

    Note: If you want to force the reminder bubble to appear for testing purposes, you can do so by putting the app in immersive mode, turning off the screen with the power button, and then turning the screen back on again within 5 seconds.

  3. Immersive mode—This is the app in immersive mode, with the system bars and other UI controls hidden. You can achieve this state with either IMMERSIVE or IMMERSIVE_STICKY.
  4. Sticky flag—This is the UI you see if you use the IMMERSIVE_STICKY flag, and the user swipes to display the system bars. Semi-transparent bars temporarily appear and then hide again. The act of swiping doesn't clear any flags, nor does it trigger your system UI visibility change listeners, because the transient appearance of the system bars isn't considered a UI visibility change.

Note: Remember that the "immersive" flags only take effect if you use them in conjunction withSYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN, or both. You can just use one or the other, but it's common to hide both the status and the navigation bar when you're implementing "full immersion" mode.

Choose an Approach


The flags SYSTEM_UI_FLAG_IMMERSIVE and SYSTEM_UI_FLAG_IMMERSIVE_STICKY both provide an immersive experience, but with the differences in behavior described above. Here are examples of when you would use one flag vs. the other:

  • If you're building a book reader, news reader, or a magazine, use the IMMERSIVE flag in conjunction withSYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION. Because users may want to access the action bar and other UI controls somewhat frequently, but not be bothered with any UI elements while flipping through content, IMMERSIVE is a good option for this use case.
  • If you're building a truly immersive app, where you expect users to interact near the edges of the screen and you don't expect them to need frequent access to the system UI, use the IMMERSIVE_STICKY flag in conjunction with SYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION. For example, this approach might be suitable for a game or a drawing app.
  • If you're building a video player or some other app that requires minimal user interaction, you can probably get by with the lean back approach, available since Android 4.0 (API Level 14). For this type of app, simply using SYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION should be sufficient. Don't use the "immersive" flags in this case.

Use Non-Sticky Immersion


When you use the SYSTEM_UI_FLAG_IMMERSIVE flag, it hides the system bars based on what other UI flags you have set (SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN, or both). When the user swipes inward in a system bars region, the system bars reappear and remain visible.

It's good practice to include other system UI flags (such as SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION andSYSTEM_UI_FLAG_LAYOUT_STABLE) to keep the content from resizing when the system bars hide and show. You should also make sure that the action bar and other UI controls are hidden at the same time. This snippet demonstrates how to hide and show the status and navigation bars, without resizing the content:

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

You may also want to implement the following in conjunction with the IMMERSIVE flag to provide a better user experience:

  • Register a listener so that your app can get notified of system UI visibility changes, as described inResponding to UI Visibility Changes.
  • Implement onWindowFocusChanged(). If you gain window focus, you may want to re-hide the system bars. If you lose window focus, for example due to a dialog or pop up menu showing above your app, you'll probably want to cancel any pending "hide" operations you previously scheduled with Handler.postDelayed() or something similar.
  • Implement a GestureDetector that detects onSingleTapUp(MotionEvent), to allow users to manually toggle the visibility of the system bars by touching your content. Simple click listeners aren't the best solution for this because they get triggered even if the user drags a finger across the screen (assuming the click target takes up the whole screen).

For more discussion of these topics, watch the video DevBytes: Android 4.4 Immersive Mode.

Use Sticky Immersion


When you use the SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag, an inward swipe in the system bars areas causes the bars to temporarily appear in a semi-transparent state, but no flags are cleared, and your system UI visibility change listeners are not triggered. The bars automatically hide again after a short delay, or if the user interacts with the middle of the screen.

Figure 2 shows the semi-transparent system bars that briefly appear and then hide again when you use theIMMERSIVE_STICKY flag.

system bars

Figure 2. Auto-hiding system bars.

Below is a simple approach to using this flag. Any time the window receives focus, simply set theIMMERSIVE_STICKY flag, along with the other flags discussed in Use IMMERSIVE. For example:

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

Note: If you like the auto-hiding behavior of IMMERSIVE_STICKY but need to show your own UI controls as well, just use IMMERSIVE combined with Handler.postDelayed() or something similar to re-enter immersive mode after a few seconds.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值