• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Using Immersive Full-Screen Mode
2
3trainingnavtop=true
4
5@jd:body
6
7<div id="tb-wrapper">
8<div id="tb">
9
10<!-- table of contents -->
11<h2>This lesson teaches you to</h2>
12<ol>
13  <li><a href="#compare">Choose an Approach</a></li>
14  <li><a href="#nonsticky">Use Non-Sticky Immersion</a></li>
15  <li><a href="#sticky">Use Sticky Immersion</a></li>
16</ol>
17
18
19<!-- other docs (NOT javadocs) -->
20<h2>You should also read</h2>
21
22<ul>
23    <li>
24        <a href="{@docRoot}training/appbar/index.html">Adding the App Bar</a>
25    </li>
26    <li>
27        <a href="{@docRoot}design/patterns/fullscreen.html">
28        Android Design Guide
29        </a>
30    </li>
31</ul>
32
33
34
35<h2>Try it out</h2>
36
37<div class="download-box">
38  <a href="{@docRoot}samples/ImmersiveMode/index.html"
39class="button">Get the sample</a>
40 <p class="filename">ImmersiveMode sample</p>
41</div>
42
43</div>
44</div>
45
46<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=cBi8fjv90E4">
47<div>
48    <h3>Video</h3>
49    <p>DevBytes: Android 4.4 Immersive Mode</p>
50</div>
51</a>
52
53<p>Android 4.4 (API Level 19) introduces a new
54{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} flag for
55{@link android.view.View#setSystemUiVisibility setSystemUiVisibility()} that lets your app
56go truly "full screen." This flag, when combined with the
57{@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} and
58{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flags, hides the navigation and status
59bars and lets your app capture all touch events on the screen.</p>
60
61<p>When immersive full-screen mode is
62enabled, your activity continues to receive all touch events. The user can reveal the
63system bars with an inward swipe along the region where the system bars normally appear.
64This clears the {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} flag
65(and the {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flag, if applied) so the
66system bars become visible. This also triggers your
67{@link android.view.View.OnSystemUiVisibilityChangeListener},
68if set. However, if you'd like the system bars to automatically hide
69again after a few moments, you can instead use the
70{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY} flag. Note that the
71"sticky" version of the flag doesn't trigger any listeners, as system bars temporarily
72shown in this mode are in a transient state.
73</p>
74
75<p>Figure 1 illustrates the different "immersive mode" states:</p>
76
77 <img src="{@docRoot}images/training/imm-states.png"
78  alt="system bars">
79<p class="img-caption"><strong>Figure 1.</strong> Immersive mode states.</p>
80
81<p>In figure 1:</p>
82<ol>
83<li><strong>Non-immersive mode</strong>&mdash;This is how the app
84appears before it enters immersive mode. It is also how the app appears if you use the
85{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag, and the user swipes to
86display the system bars, thereby clearing the {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} and
87{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} flags. Once these flags are cleared, the system
88bars reappear and remain visible.</li>
89
90<p>Note that it's best practice to
91 keep all UI controls in sync with the system bars, to minimize the
92 number of states your screen can be in. This provides a more seamless user experience. So
93 here all UI controls are displayed along with the status bars. Once the app enters
94 immersive mode, the UI controls are hidden along with the system bars.
95 To ensure that your UI visibility stays in sync with system bar visibility, make sure to
96 provide an appropriate {@link android.view.View.OnSystemUiVisibilityChangeListener}
97 to watch for changes, as described in
98 <a href="visibility.html">Responding to UI Visibility Changes</a>.</p></li>
99
100<li><strong>Reminder bubble</strong>&mdash;The system displays a reminder bubble
101the first time users enter
102immersive mode in your app. The reminder bubble reminds users how to display
103the system bars.
104<p class="note"><strong>Note:</strong> If you want to force the reminder bubble to appear
105for testing purposes, you can do so by putting the app in immersive mode, turning off the
106screen with the power button, and then turning the screen back on again within 5 seconds.
107</p></li>
108
109<li><strong>Immersive mode</strong>&mdash;This is the app in immersive mode, with the
110system bars and other UI controls hidden. You can achieve this state with either
111{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} or
112 {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY}. </li>
113
114<li><strong>Sticky flag</strong>&mdash;This is the UI you see if you use the
115{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag,
116and the user swipes to display the system bars. Semi-transparent bars temporarily appear and then
117hide again. The act of swiping doesn't clear any flags, nor does it trigger your
118system UI visibility change listeners, because the transient appearance of the system bars isn't
119considered a UI visibility change.</li>
120</ol>
121
122<p class="note"><strong>Note:</strong> Remember that the "immersive" flags only take effect
123if you use them in conjunction with {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION},
124{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}, or
125 both. You can just use one or the other, but it's common to hide both the status and the
126 navigation bar when you're implementing "full immersion" mode.</p>
127
128 <h2 id="compare">Choose an Approach</h2>
129
130 <p>The flags  {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} and
131 {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY} both provide an immersive
132 experience, but with the differences in behavior described above. Here are
133 examples of when you would use one flag vs. the other:</p>
134
135<ul>
136<li>If you're building a book reader, news reader, or a magazine, use
137the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag in conjunction
138with {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} and
139{@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}. Because users may want to access
140the action bar and other UI controls somewhat frequently, but not be bothered with any UI
141elements while flipping through content,
142{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} is a good option for this
143use case.</li>
144
145<li>If you're building a truly immersive app, where you expect users to interact near
146the edges of the screen and you don't expect them to need frequent access to the system
147UI, use the
148{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag
149in conjunction with {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN} and
150{@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}. For example, this approach
151might be suitable for a game or a drawing app.</li>
152
153<li>If you're building a video player or some other app that requires minimal user
154interaction, you can probably get by with the <a href="{@docRoot}design/patterns/fullscreen.html">
155lean back</a> approach, available since
156Android 4.0 (API Level 14). For this type of app, simply using
157{@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}
158 and {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} should be
159sufficient. Don't use the "immersive" flags in this case.</li>
160</ul>
161
162<h2 id="nonsticky">Use Non-Sticky Immersion</h2>
163
164 <p>When you use the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE} flag, it hides
165 the system bars based on what other UI flags you have set
166 ({@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION},
167 {@link android.view.View#SYSTEM_UI_FLAG_FULLSCREEN}, or
168 both). When the user swipes inward in a system bars region, the
169system bars reappear and remain visible.</p>
170
171<p>It's good practice to include other system UI flags (such as
172{@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} and
173{@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE}) to keep the content from resizing
174when the system bars hide and show. You should also make sure that the action bar and other
175UI controls are hidden at the same time. This snippet demonstrates how to hide and show the
176status and navigation bars, without resizing the content:</p>
177
178<pre>
179// This snippet hides the system bars.
180private void hideSystemUI() {
181    // Set the IMMERSIVE flag.
182    // Set the content to appear under the system bars so that the content
183    // doesn't resize when the system bars hide and show.
184    mDecorView.setSystemUiVisibility(
185            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
186            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
187            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
188            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
189            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
190            | View.SYSTEM_UI_FLAG_IMMERSIVE);
191}
192
193// This snippet shows the system bars. It does this by removing all the flags
194// except for the ones that make the content appear under the system bars.
195private void showSystemUI() {
196    mDecorView.setSystemUiVisibility(
197            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
198            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
199            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
200}
201</pre>
202
203
204<p>You may also want to implement the following in conjunction with the
205{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} flag to provide a better user
206experience:</p>
207
208<ul>
209<li>Register a listener so that your app can get notified of system UI visibility changes,
210as described in <a href="visibility.html">Responding to UI Visibility Changes</a>.</li>
211
212<li>Implement {@link android.app.Activity#onWindowFocusChanged onWindowFocusChanged()}.
213If you gain window focus, you may want to re-hide the system bars.
214If you lose window focus, for example due to a dialog or pop up menu showing above your app,
215you'll probably want to cancel any pending "hide" operations you previously scheduled
216with {@link android.os.Handler#postDelayed Handler.postDelayed()} or something similar.</li>
217
218<li>Implement a {@link android.view.GestureDetector} that detects
219{@link android.view.GestureDetector.OnGestureListener#onSingleTapUp}, to allow users to
220manually toggle the visibility of the system bars by touching your content.
221Simple click listeners aren't the best solution for this because they get triggered even
222if the user drags a finger across the screen (assuming the click target takes up the whole
223screen).
224</li>
225
226</ul>
227
228<p>
229For more discussion of these topics, watch the video
230<a class ="external-link" href="http://www.youtube.com/embed/cBi8fjv90E4">DevBytes:
231 Android 4.4 Immersive Mode</a>.</p>
232
233<h2 id="sticky">Use Sticky Immersion</h2>
234
235<p>When you use the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY} flag,
236an inward swipe in the system bars areas causes the bars to temporarily appear in a
237semi-transparent state, but no flags are cleared, and your
238system UI visibility change listeners are not triggered. The bars
239automatically hide again after a short delay, or if the user interacts with the middle of the
240screen.</p>
241
242<p>Figure 2 shows the semi-transparent system bars that briefly appear and then hide again
243when you use the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag.</p>
244
245 <img src="{@docRoot}images/training/imm-sticky.png"
246  alt="system bars">
247<p class="img-caption"><strong>Figure 2.</strong> Auto-hiding system bars.</p>
248
249<p>Below is a simple approach to using this flag. Any time the window receives focus, simply
250set the {@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY} flag, along
251with the other flags discussed in <a href="#nonsticky">Use IMMERSIVE</a>. For example:</p>
252
253<pre>
254&#64;Override
255public void onWindowFocusChanged(boolean hasFocus) {
256        super.onWindowFocusChanged(hasFocus);
257    if (hasFocus) {
258        decorView.setSystemUiVisibility(
259                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
260                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
261                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
262                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
263                | View.SYSTEM_UI_FLAG_FULLSCREEN
264                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
265}
266</pre>
267
268<p class="note"><strong>Note:</strong> If you like the auto-hiding behavior of
269{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY IMMERSIVE_STICKY}
270but need to show your own UI controls as well, just use
271{@link android.view.View#SYSTEM_UI_FLAG_IMMERSIVE IMMERSIVE} combined with
272{@link android.os.Handler#postDelayed Handler.postDelayed()} or something similar to
273re-enter immersive mode after a few seconds.</p>
274