page.title=Using Immersive Full-Screen Mode trainingnavtop=true @jd:body
DevBytes: Android 4.4 Immersive Mode
Android 4.4 (API Level 19) introduces a new {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} flag for {@link android.view.View#setSystemUiVisibility setSystemUiVisibility()} that lets your app go truly "full screen." This flag, when combined with the {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} and {@link android.view.View#SYSTEM_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 the {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} flag (and the {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flag, if applied) so the system bars become visible. This also triggers your {@link android.view.View.OnSystemUiVisibilityChangeListener}, if set. However, if you'd like the system bars to automatically hide again after a few moments, you can instead use the {@link android.view.View#SYSTEM_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:
In figure 1:
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 {@link android.view.View.OnSystemUiVisibilityChangeListener} to watch for changes, as described in Responding to UI Visibility Changes.
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.
Note: Remember that the "immersive" flags only take effect if you use them in conjunction with {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link android.view.View#SYSTEM_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.
The flags {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} and {@link android.view.View#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:
When you use the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} flag, it hides the system bars based on what other UI flags you have set ({@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link android.view.View#SYSTEM_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 {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} and {@link android.view.View#SYSTEM_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 {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag to provide a better user experience:
For more discussion of these topics, watch the video DevBytes: Android 4.4 Immersive Mode.
When you use the {@link android.view.View#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 the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag.
Below is a simple approach to using this flag. Any time the window receives focus, simply set the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_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 {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} but need to show your own UI controls as well, just use {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} combined with {@link android.os.Handler#postDelayed Handler.postDelayed()} or something similar to re-enter immersive mode after a few seconds.