
本文共 13720 字,大约阅读时间需要 45 分钟。
文章目录
Enable fullscreen mode
Some content is best experienced fullscreen, like videos, games, image galleries, books, and slides in a presentation. This page shows how you can engage users more deeply with content in fullscreen and protect users from exiting the app accidentally.
You might be tempted to enable fullscreen mode just to maximize screen space for your app. But be mindful of how often users jump in and out of apps to check notifications, do impromptu searches, and more. Using fullscreen causes users to lose easy access to system navigation, so you should use fullscreen mode only when the benefit to the user experience goes beyond simply receiving a little extra space (such as to avoid accidental exits during a game or delivering a valuable immersive exerience for images, videos, and books).
Fullscreen options
Android offers three options to making your app fullscreen: Lean Back, Immersive, and Immersive Sticky. In all three approaches, the system bars are hidden and your activity continues to receive all touch events. The difference between them is how the user can bring the system bars back into view.
The following is a description of each of the different options. For example code, jump down to .
Lean back
The lean back mode is for fullscreen experiences in which users won’t be interacting heavily with the screen, such as while watching a video.
When users want to bring back the system bars, they simply tap the screen anywhere.
To enable lean back mode, call setSystemUiVisibility()
and pass SYSTEM_UI_FLAG_FULLSCREEN
and SYSTEM_UI_FLAG_HIDE_NAVIGATION
.
When the system bars re-appear, you can receive a callback to make other appropriate updates to your UI. See .
Immersive
The immersive mode is intended for apps in which the user will be heavily interacting with the screen. Examples are games, viewing images in a gallery, or reading paginated content, like a book or slides in a presentation.
When users need to bring back the system bars, they swipe from any edge where a system bar is hidden. By requiring this more deliberate gesture, the user’s engagement with your app won’t be interrupted by accidental touches and swipes.
To enable immersive mode, call setSystemUiVisibility()
and pass the SYSTEM_UI_FLAG_IMMERSIVE
flag in conjunction with SYSTEM_UI_FLAG_FULLSCREEN
and SYSTEM_UI_FLAG_HIDE_NAVIGATION
.
If your app has its own controls that aren’t needed when a user is immersed in content, make them disappear and reappear in sync with the system bars. This recommendation also applies to any app-specific gestures you might have for hiding and showing app controls. For example, if touching anywhere on the screen toggles the appearance of a toolbar or a palette, then it should also toggle the appearance of system bars.
When the system bars re-appear, you can receive a callback to make other appropriate updates to your UI. See .
Sticky immersive
In the regular immersive mode, any time a user swipes from an edge, the system takes care of revealing the system bars—your app won’t even be aware that the gesture occurred. So if the user might actually need to swipe from the edge of the screen as part of the primary app experience—such as when playing a game that requires lots of swiping or using a drawing app—you should instead enable the “sticky” immersive mode.
While in sticky immersive mode, if the user swipes from an edge with a system bar, system bars appear but they’re semi-transparent, and the touch gesture is passed to your app so it can also respond to the gesture.
For example, in a drawing app that uses this approach, if the user wants to draw a line that begins at the very edge of the screen, swiping from the edge reveals the system bars and also starts drawing a line that begins at the very edge. The bars automatically disappear after a few seconds of no interaction or as soon as the user touches or gestures anywhere outside the system bars.
To enable sticky immersive mode, call setSystemUiVisibility()
and pass the SYSTEM_UI_FLAG_IMMERSIVE_STICKY
flag in conjunction with SYSTEM_UI_FLAG_FULLSCREEN
and SYSTEM_UI_FLAG_HIDE_NAVIGATION
.
With stick immersive, you cannot receive a callback when the system UI visibility changes. So if you want the auto-hiding behavior of sticky immersive mode, but still want to know when the system UI re-appears in order to show your own UI controls as well, use the regular IMMERSIVE
flag and use Handler.postDelayed()
or something similar to re-enter immersive mode after a few seconds.
Enable fullscreen mode
Regardless of which fullscreen mode you want to use, you must call setSystemUiVisibility()
and pass it either SYSTEM_UI_FLAG_HIDE_NAVIGATION
, SYSTEM_UI_FLAG_FULLSCREEN
, or both. You can include either SYSTEM_UI_FLAG_IMMERSIVE
(for regular immersive mode) or SYSTEM_UI_FLAG_IMMERSIVE_STICKY
(for sticky immersive mode), or exclude both to enable lean back mode.
It’s good practice to include other system UI flags (such as SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
and SYSTEM_UI_FLAG_LAYOUT_STABLE
) to prevent your layout 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.
The following code shows how to hide and show the status and navigation bars in your activity, without resizing your layout in response to the changing screen space:
@Overridepublic void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { hideSystemUI(); }}private void hideSystemUI() { // Enables regular immersive mode. // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE. // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_IMMERSIVE // Set the content to appear under the system bars so that the // content doesn't resize when the system bars hide and show. | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // Hide the nav bar and status bar | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);}// Shows the system bars by removing all the flags// except for the ones that make the content appear under the system bars.private void showSystemUI() { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);}
You might also want to implement the following to provide a better user experience:
- To provide a seamless transition between states, keep the visibility of all UI controls in sync with the system bars. Once the app enters immersive mode, any UI controls should also hide along with the system bars, and then also reappear when the system UI reappears. To do so, implement
View.OnSystemUiVisibilityChangeListener
to receive callbacks, as described in . - 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 withHandler.postDelayed()
or something similar. - Implement a
GestureDetector
that detectsonSingleTapUp(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).
Note: When you use the SYSTEM_UI_FLAG_IMMERSIVE_STICKY
flag, a swipe causes the system UI to temporarily appear in a semi-transparent state, but no flags are cleared and your system UI visibility change listeners are not triggered.
Additional sample code
To see more code using different fullscreen modes, see the following samples:
Other considerations
In Android Automotive OS, the car manufacturer can block fullscreen mode.
准备
IDE:
Android Studio 4.1.1Build #AI-201.8743.12.41.6953283, built on November 5, 2020Runtime version: 1.8.0_242-release-1644-b01 amd64VM: OpenJDK 64-Bit Server VM by JetBrains s.r.oWindows 10 10.0
Android Virtual Devices:
Name: Pixel_2_API_28CPU/ABI: Google Play Intel Atom (x86)Path: C:\Users\86188\.android\avd\Pixel_2_API_28.avdTarget: google_apis_playstore [Google Play] (API level 28)Skin: pixel_2SD Card: 512Mfastboot.chosenSnapshotFile: runtime.network.speed: fullhw.accelerometer: yeshw.device.name: pixel_2hw.lcd.width: 1080hw.initialOrientation: Portraitimage.androidVersion.api: 28tag.id: google_apis_playstorehw.mainKeys: nohw.camera.front: emulatedavd.ini.displayname: Pixel 2 API 28hw.gpu.mode: autohw.ramSize: 1536PlayStore.enabled: truefastboot.forceColdBoot: nohw.cpu.ncore: 4hw.keyboard: yeshw.sensors.proximity: yeshw.dPad: nohw.lcd.height: 1920vm.heapSize: 256skin.dynamic: yeshw.device.manufacturer: Googlehw.gps: yeshw.audioInput: yesimage.sysdir.1: system-images\android-28\google_apis_playstore\x86\showDeviceFrame: yeshw.camera.back: virtualsceneAvdId: Pixel_2_API_28hw.lcd.density: 420hw.arc: falsehw.device.hash2: MD5:55acbc835978f326788ed66a5cd4c9a7fastboot.forceChosenSnapshotBoot: nofastboot.forceFastBoot: yeshw.trackBall: nohw.battery: yeshw.sdCard: yestag.display: Google Playruntime.network.latency: nonedisk.dataPartition.size: 6442450944hw.sensors.orientation: yesavd.ini.encoding: UTF-8hw.gpu.enabled: yes
注意:以下示例仅在安卓虚拟设备上运行测试,并没有在真实的设备上运行测试。
项目
效果:
新建项目,选择 Empty Activity,在配置项目时,Minimum SDK
选择 API 16: Android 4.1 (Jelly Bean)
编辑 src\main\java\com\mk\MainActivity.java
布局文件,添加一个 RadioGroup
组件,然后在其中加入四个 RadioButton
组件:
编辑 MainActivity
文件,分别为四个 RadioButton
绑定点击事件:
package com.mk;import android.os.Bundle;import android.view.View;import android.widget.RadioButton;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((RadioButton) findViewById(R.id.radioButtonLeanBack)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { leanBack(); } }); ((RadioButton) findViewById(R.id.radioButtonImmersive)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { immersive(); } }); ((RadioButton) findViewById(R.id.radioButtonStickyImmersive)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stickyImmersive(); } }); ((RadioButton) findViewById(R.id.radioButtonShowSystemUi)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showSystemUI(); } }); } private void leanBack() { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( // Set the content to appear under the system bars so that the // content doesn't resize when the system bars hide and show. View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // Hide the nav bar and status bar | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION ); } private void immersive() { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_IMMERSIVE // Set the content to appear under the system bars so that the // content doesn't resize when the system bars hide and show. | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // Hide the nav bar and status bar | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION ); } private void stickyImmersive() { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY // Set the content to appear under the system bars so that the // content doesn't resize when the system bars hide and show. | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // Hide the nav bar and status bar | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION ); } // Shows the system bars by removing all the flags // except for the ones that make the content appear under the system bars. private void showSystemUI() { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN ); }}
参考
发表评论
最新留言
关于作者
