| page.title=Using Immersive Full-Screen Mode |
| |
| trainingnavtop=true |
| |
| @jd:body |
| |
| <div id="tb-wrapper"> |
| <div id="tb"> |
| |
| <!-- table of contents --> |
| <h2>This lesson teaches you to</h2> |
| <ol> |
| <li><a href="#compare">Choose an Approach</a></li> |
| <li><a href="#nonsticky">Use Non-Sticky Immersion</a></li> |
| <li><a href="#sticky">Use Sticky Immersion</a></li> |
| </ol> |
| |
| |
| <!-- other docs (NOT javadocs) --> |
| <h2>You should also read</h2> |
| |
| <ul> |
| <li> |
| <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> API Guide |
| </li> |
| <li> |
| <a href="{@docRoot}design/patterns/fullscreen.html"> |
| Android Design Guide |
| </a> |
| </li> |
| </ul> |
| |
| |
| |
| <h2>Try it out</h2> |
| |
| <div class="download-box"> |
| <a href="{@docRoot}samples/ImmersiveMode/index.html" |
| class="button">Get the sample</a> |
| <p class="filename">ImmersiveMode sample</p> |
| </div> |
| |
| </div> |
| </div> |
| |
| <a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=cBi8fjv90E4"> |
| <div> |
| <h3>Video</h3> |
| <p>DevBytes: Android 4.4 Immersive Mode</p> |
| </div> |
| </a> |
| |
| <p>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.</p> |
| |
| <p>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. |
| </p> |
| |
| <p>Figure 1 illustrates the different "immersive mode" states:</p> |
| |
| <img src="{@docRoot}images/training/imm-states.png" |
| alt="system bars"> |
| <p class="img-caption"><strong>Figure 1.</strong> Immersive mode states.</p> |
| |
| <p>In figure 1:</p> |
| <ol> |
| <li><strong>Non-immersive mode</strong>—This is how the app |
| appears before it enters immersive mode. It is also how the app appears if you use the |
| {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag, and the user swipes to |
| display the system bars, thereby clearing the {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} and |
| {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flags. Once these flags are cleared, the system |
| bars reappear and remain visible.</li> |
| |
| <p>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 |
| <a href="visibility.html">Responding to UI Visibility Changes</a>.</p></li> |
| |
| <li><strong>Reminder bubble</strong>—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. |
| <p class="note"><strong>Note:</strong> 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. |
| </p></li> |
| |
| <li><strong>Immersive mode</strong>—This is the app in immersive mode, with the |
| system bars and other UI controls hidden. You can achieve this state with either |
| {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} or |
| {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY}. </li> |
| |
| <li><strong>Sticky flag</strong>—This is the UI you see if you use the |
| {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY 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.</li> |
| </ol> |
| |
| <p class="note"><strong>Note:</strong> 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.</p> |
| |
| <h2 id="compare">Choose an Approach</h2> |
| |
| <p>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:</p> |
| |
| <ul> |
| <li>If you're building a book reader, news reader, or a magazine, use |
| the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag in conjunction |
| with {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} and |
| {@link android.view.View#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, |
| {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} is a good option for this |
| use case.</li> |
| |
| <li>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 |
| {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag |
| in conjunction with {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} and |
| {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}. For example, this approach |
| might be suitable for a game or a drawing app.</li> |
| |
| <li>If you're building a video player or some other app that requires minimal user |
| interaction, you can probably get by with the <a href="{@docRoot}design/patterns/fullscreen.html"> |
| lean back</a> approach, available since |
| Android 4.0 (API Level 14). For this type of app, simply using |
| {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} |
| and {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} should be |
| sufficient. Don't use the "immersive" flags in this case.</li> |
| </ul> |
| |
| <h2 id="nonsticky">Use Non-Sticky Immersion</h2> |
| |
| <p>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.</p> |
| |
| <p>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:</p> |
| |
| <pre> |
| // 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); |
| } |
| </pre> |
| |
| |
| <p>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:</p> |
| |
| <ul> |
| <li>Register a listener so that your app can get notified of system UI visibility changes, |
| as described in <a href="visibility.html">Responding to UI Visibility Changes</a>.</li> |
| |
| <li>Implement {@link android.app.Activity#onWindowFocusChanged 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 {@link android.os.Handler#postDelayed Handler.postDelayed()} or something similar.</li> |
| |
| <li>Implement a {@link android.view.GestureDetector} that detects |
| {@link android.view.GestureDetector.OnGestureListener#onSingleTapUp}, 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). |
| </li> |
| |
| </ul> |
| |
| <p> |
| For more discussion of these topics, watch the video |
| <a class ="external-link" href="http://www.youtube.com/embed/cBi8fjv90E4">DevBytes: |
| Android 4.4 Immersive Mode</a>.</p> |
| |
| <h2 id="sticky">Use Sticky Immersion</h2> |
| |
| <p>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.</p> |
| |
| <p>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.</p> |
| |
| <img src="{@docRoot}images/training/imm-sticky.png" |
| alt="system bars"> |
| <p class="img-caption"><strong>Figure 2.</strong> Auto-hiding system bars.</p> |
| |
| <p>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 <a href="#nonsticky">Use IMMERSIVE</a>. For example:</p> |
| |
| <pre> |
| @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);} |
| } |
| </pre> |
| |
| <p class="note"><strong>Note:</strong> 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.</p> |