沉浸式模式

沉浸式模式

什么是沉浸式模式?

首先,看一下Android官方对这个概念的描述 Enable fullscreen mode
system-ui

如果无法访问,可尝试访问中文站
Enable fullscreen mode
system-ui

沉浸式这个概念不好理解,也不好解释。通常解释就是身临其境的概念。个人理解就是你完全至于某一状态,没有其它东西的打扰。对于Android来讲就是,你完全沉浸于应用的内容,不受其它内容的打扰,比如:状栏态和导航栏 。再简单解释就是,应用是全屏的,没有状栏态和导航栏。

Android系统栏是用于显示通知、设备状态通信和设备导航的屏幕区域。通常系统栏(包括状栏态和导航栏,如图1所示)会和应用程序一起显示, 有些应用程序会显示沉浸式的内容,如电影或图像【通常是全屏】, 它们可以暂时变暗的系统栏图标少分心的经验,或暂时隐藏系统栏以获得完全身临其境的体验。

下图来自android开发者官网对沉浸式介绍的文档。

调暗状态栏

Android4.1(API14)级以上,提供了让系统栏变暗的方法,之前版本没有提供。

当您使用这种方法时,应用的内容不会改变大小,但是系统中的图标会在视觉上后退。只要用户接触到屏幕的状态栏或导航栏区域,两个栏就会完全可见。这种方法的优点是,这些系统栏仍然存在,但是它们的细节被掩盖了,从而创造了一种身临其境的体验,同时又不牺牲对系统栏的方便。

1
2
3
4
// This example uses decor view, but you can use any visible view.
View decorView = getActivity().getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView.setSystemUiVisibility(uiOptions);

只要用户接触到屏幕的状态栏或导航栏区域,这些标志就会被清楚。 如果你想要再次变暗系统栏,你需要重新设置这些标识。

清楚标志

1
2
3
4
View decorView = getActivity().getWindow().getDecorView();
// Calling setSystemUiVisibility() with a value of 0 clears
// all flags.
decorView.setSystemUiVisibility(0);

隐藏状态栏

隐藏状态栏 Android 4.0 之前

使用主题

1
2
3
4
5
<application
...
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
...
</application>

使用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If the Android version is lower than Jellybean, use this call to hide
// the status bar.
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
setContentView(R.layout.activity_main);
}
...
}

同时,为了不让布局因SystemUI的可见或隐藏而重新layout,可以给Window添加FLAG_LAYOUT_IN_SCREEN和FLAG_LAYOUT_NO_LIMITS这2个标记位,这样SystemUI出现时候是overlay在布局内容的上面。如:

1
2
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);    
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);****

隐藏状态栏 Android 4.1 and Higher

1
2
3
4
5
6
7
8
View decorView = getWindow().getDecorView();
// Hide the status bar.
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
// Remember that you should never show the action bar if the
// status bar is hidden, so hide that too if necessary.
ActionBar actionBar = getActionBar();
actionBar.hide();

请注意以下几点:

  • 一旦UI标志被清除(例如,通过导航离开活动),如果您想再次隐藏条形图,您的应用程序需要重置它们。有关如何侦听UI可见性更改的讨论,请参阅响应UI可见性更改,以便您的应用可以做出相应响应。
  • 你在哪里设置UI标志会有所不同。如果您将系统栏隐藏在活动的 onCreate()方法中,并且用户按Home,则系统栏将重新出现。当用户重新打开活动时,onCreate() 不会被调用,因此系统栏将保持可见。如果您希望系统用户界面更改在用户导航进出您的活动时保持不变,请在onResume() 或中设置UI标志 onWindowFocusChanged()。
  • setSystemUiVisibility() 如果您调用的视图可见,则此方法只有效果。
  • 离开视图导致设置的标志setSystemUiVisibility() 被清除。
  • 状态栏出现时,UI会resize.

使内容出现在状态栏的后面

在Android 4.1及更高版本中,您可以将应用程序的内容设置为显示在状态栏的后面,以便在状态栏隐藏和显示时不会调整内容的大小。要做到这一点,请使用 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN。您可能还需要用来 SYSTEM_UI_FLAG_LAYOUT_STABLE帮助您的应用保持稳定的布局。

当你使用这种方法时,你有责任确保应用程序的UI的关键部分(例如,地图应用程序中的内置控件)最终不会被系统栏覆盖。这可能会使您的应用无法使用。在大多数情况下,您可以通过将该android:fitsSystemWindows属性添加到您的XML布局文件(设置为) 来处理此问题true。这会调整父级的填充ViewGroup 以为系统窗口留出空间。这对大多数应用来说已经足够了

但是,在某些情况下,您可能需要修改默认填充以获取应用的所需布局。要直接操纵内容相对于系统栏(占据称为窗口的“内容插页”的空间)的方式,请覆盖fitSystemWindows(Rect insets)。fitSystemWindows()当窗口的内容插入已更改时,该方法由视图层次结构调用,以允许窗口相应地调整其内容。通过重写此方法,您可以处理插入(因此您的应用程序的布局),无论你想要。

1
2
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

隐藏导航栏

隐藏导航栏

1
2
3
4
5
6
View decorView = getWindow().getDecorView();
// hide the navigation bar.
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);

应用内容在 Navigation Bar后面

SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

此时,点击UI会导致SystemUI都出来。

全屏模式

Immersive

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.

1
2
3
4
5
6

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE;
decorView.setSystemUiVisibility(uiOptions);

开始显示时,系统会提示Swipe, 就会出现状态栏和导航栏。Swipe之后,状态栏不消失

Sticky immersive

全屏时,Swipe, 就会出现状态栏和导航栏。但是他们是半透明的。
Swipe之后,状态栏过一会会自动消失。

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.

1
2
3
4
5
6

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);

Enable fullscreen mode