274 lines
12 KiB
Plaintext
274 lines
12 KiB
Plaintext
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>
|