全屏沉浸式应用

    这节课将教您

    1. 选择一种沉浸方式
    2. 使用非粘性沉浸模式
    3. 使用粘性沉浸模式

    Adnroid 4.4(API level 19)中引入为引入了一个新标签SYSTEM_UI_FLAG_IMMERSIVE,它可以让应用进入真正的全屏模式。当这个标签与SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN一起使用的时候,导航栏和状态栏就会隐藏,让你的应用可以接受屏幕上任何地方的触摸事件。

    当沉浸式全屏模式启用的时候,你的Activity会继续接受各类的触摸事件。用户可以通过在边缘区域向内滑动来让系统栏重新显示。这个操作清空了SYSTEM_UI_FLAG_HIDE_NAVIGATION(和SYSTEM_UI_FLAG_FULLSCREEN,如果有的话)两个标签,因此系统栏重新变得可见。如果设置了的话,这个操作同时也触发了View.OnSystemUiVisibilityChangeListener。然而, 如果你想让系统栏在一段时间后自动隐藏的话,你应该使用SYSTEM_UI_FLAG_IMMERSIVE_STICKY标签。请注意,带有’sticky’的标签不会触发任何的监听器,因为在这个模式下展示的系统栏是处于暂时(transient)的状态。

    图1展示了各种不同的“沉浸式”状态

    图1. 沉浸模式状态.

    在上图中:

    1. 提示气泡——第一次进入沉浸模式时,系统将会显示一个提示气泡,提示用户如何再让系统栏显示出来。

    2. 粘性标签——这就是你设置了IMMERSIVE_STICKY标签时的UI状态,用户会向内滑动以展示系统栏。半透明的系统栏会临时的进行显示,一段时间后自动隐藏。滑动的操作并不会清空任何标签,也不会触发系统UI可见性的监听器,因为暂时显示的导航栏并不被认为是一种可见性状态的变化。

    SYSTEM_UI_FLAG_IMMERSIVE与都提供了沉浸式的体验,但是在上面的描述中,他们是不一样的,下面讲解一下什么时候该用哪一种标签。

    • 如果你在写一款图书浏览器、新闻杂志阅读器,请将IMMERSIVE标签与SYSTEM_UI_FLAG_FULLSCREEN,SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用。因为用户可能会经常访问Action Bar和一些UI控件,又不希望在翻页的时候有其他的东西进行干扰。IMMERSIVE在该种情况下就是个很好的选择。
    • 如果你在打造一款真正的沉浸式应用,而且你希望屏幕边缘的区域也可以与用户进行交互,并且用户也不会经常访问系统UI。这个时候就要将IMMERSIVE_STICKYSYSTEM_UI_FLAG_FULLSCREEN SYSTEM_UI_FLAG_HIDE_NAVIGATION两个标签一起使用。比如做一款游戏或者绘图应用就很合适。
    • 如果你在打造一款视频播放器,并且需要少量的用户交互操作。你可能就需要之前版本的一些方法了(从Android 4.0开始)。对于这种应用,简单的使用SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_HIDE_NAVIGATION就足够了,不需要使用immersive标签。

    当你使用SYSTEM_UI_FLAG_IMMERSIVE标签的时候,它是基于其他设置过的标签(SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN)来隐藏系统栏的。当用户向内滑动,系统栏重新显示并保持可见。

    用其他的UI标签(如SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONSYSTEM_UI_FLAG_LAYOUT_STABLE)来防止系统栏隐藏时内容区域大小发生变化是一种很不错的方法。你也需要确保Action Bar和其他系统UI控件同时进行隐藏。下面这段代码展示了如何在不改变内容区域大小的情况下,隐藏与显示状态栏和导航栏。

    • 注册一个监听器来监听系统UI的变化。
    • 实现onWindowFocusChanged()函数。如果窗口获取了焦点,你可能需要对系统栏进行隐藏。如果窗口失去了焦点,比如说弹出了一个对话框或菜单,你可能需要取消那些将要在Handler.postDelayed()或其他地方的隐藏操作。
    • 实现一个,它监听了onSingleTapUp(MotionEvent)事件。可以使用户点击内容区域来切换系统栏的显示状态。单纯的点击监听可能不是最好的解决方案,因为当用户在屏幕上拖动手指的时候(假设点击的内容占据了整个屏幕),这个事件也会被触发。

    更多关于此话题的讨论,可以观看这个视频 DevBytes: Android 4.4 Immersive Mode

    当使用了SYSTEM_UI_FLAG_IMMERSIVE_STICKY标签的时候,向内滑动的操作会让系统栏临时显示,并处于半透明的状态。此时没有标签会被清除,系统UI可见性监听器也不会被触发。如果用户没有进行操作,系统栏会在一段时间内自动隐藏。

    图2展示了当使用IMMERSIVE_STICKY标签时,半透明的系统栏展示与又隐藏的状态。

    imm-sticky

    图2. 自动隐藏系统栏.

    下面是一段实现代码。一旦窗口获取了焦点,只要简单的设置IMMERSIVE_STICKY与上面讨论过的其他标签即可。

    1. @Override
    2. super.onWindowFocusChanged(hasFocus);
    3. if (hasFocus) {
    4. decorView.setSystemUiVisibility(
    5. View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    6. | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    7. | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    8. | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    9. | View.SYSTEM_UI_FLAG_FULLSCREEN
    10. }