Android Tech And Thoughts.

Slide Conflict part one

Word count: 1.5kReading time: 5 min
2019/12/15 Share

开启全面屏体验 | 手势导航(一)

Android 10 中添加了新的系统导航模式,用户可以通过手势交互执行后退、返回主屏以及打开设备助手等操作
现有的三键导航模式仍被保留(后退、返回首页以及切换最近使用的应用),搭载 Android 10 及以上版本系统的所有设备都要求保留这一导航模式。
navigation.gif

本文着重为开发者介绍如何让应用支持手势导航,涵盖的主题如下:

  1. 开启全面屏体验,让应用的内容铺满整个屏幕
  2. 处理与系统UI的视觉冲突
  3. 处理与系统手势之间的冲突
  4. 各种全面屏体验场景,以及如何适配他们

全面屏体验

640.gif

我使用 “边到边”(edge to edge)一词来描述那种将内容铺满整个屏幕,以实现更沉浸式体验的应用。默认情况下,应用内容的绘制范围从顶部状态栏下方开始,延申至底部导航栏上方(状态栏和导航栏统称为系统栏)

实现了从边到边的全面屏体验后,系统栏会覆盖在应用内容前方。应用也得以通过更大幅面的内容为用户带来更具冲击力的体验。

具体来说,这意味着需要做两件事:

在导航栏后面绘制内容

由于导航栏自身的大小和突出程度已经相比以前缩小了,因此我们强烈建议,当应用在 Android 10 及以上设备中运行时,将内容拓展至导航栏后方,以提供更具吸引力的现代化 UX。
在搭载 Android 9 以及以下的设备上运行时,导航栏后绘制内容是可选的,方便根据应用情况酌情选择。做到这些事情所需的API也都向后兼容至 API 21(或AndroidX的对应版本),因此支持 Android 10 以下设备所需的额外工作量很小。
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : 使内容隐藏在statusBar后面,当然只是设置这个,可能在视觉上你并不能感觉出来,将statusBar的颜色设置为半透明,即可。通过 getWindow.setStatusBarColor()。要非常注意 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 和 SYSTEM_UI_FLAG_FULLSCREEN 的区别,后者则是隐藏状态栏。

在状态栏后面绘制内容

仅仅强调一下,是否扩展应用内容的绘制区域取决于开发者,有些情况并不适合,会影响到用户体验。不过仍可以通过fitsystemwindows属性来避免交互内容出现在系统栏后面。

系统窗口是系统绘制非交互式(对于状态栏而言)或交互式(对于导航栏而言)内容的屏幕部分。
大多数情况下,您的应用无需在状态栏或导航栏下绘制,但如果这样做,则需要确保交互元素(如按钮)没有隐藏在它们的下方。 这就是android:fitsSystemWindows =“ true”属性的默认行为所提供的:它设置View的padding以确保内容不覆盖系统窗口/

如何实现

实现边到边的全面屏体验共分为三步:

1.请求进行全面屏布局

系统本来的布局是,三个Window从上至下而列,没有谁覆盖在谁上面,分别是 statusBar Actvity Navigation
让系统将我们应用布局扩展至系统蓝后方,需要的API是视图上的 setSystemUiVisiblity() ,它接收一些值,这里我们主要关注以下几个值:

1
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
2
3
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NIVIGATION
4
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN (好像应该叫 HIDE_STATUS) //对Navigation不起作用

对于LAYOUT_FULLSCREEN,我实验了下,如果是有ActionBar的Theme,好像就没有效果了,ActionBar依然是处于status下面,并没有在其下方进行绘制,可能系统默认不能让ActionBar放在status下面,所以设置了decor的padding属性?我这么说是因为此时fullscreen还是奏效的,decor依然是全屏,只是设置了paddingTop,当然fitsysetmWindow可以达到这种效果,但是我好像并没有显式设置该属性,这是一个谜。

我们把 STABLE 标志单独拿出来讲一讲:

SYSTEM_UI_FLAG_FULLSCREEN VS SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
SYSTEM_UI_FLAG_HIDE_NAVIGATION VS SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

2.更改系统栏颜色

我们的应用布局现在已经拓展至全屏范围,因此需要同步更改一下系统栏的颜色,以便看清其后面的应用内容。

1) Android 10
在Android10上,我们只需要将系统栏颜色设为完全透明即可:

1
<style name = "Theme.MyApp">
2
	<item name="android:statusBarColor">
3
		@android:color/transparent
4
	</item>
5
</style>

这么做是因为Android10,系统栏里的内容会根据其后面的内容动态改变颜色,以确保在所有导航模式下都可见(包括时间、图标、拖拽条等)
2) Android 9及更早版本:
可以将系统栏颜色设置为半透明,从而确保其内容可见,比如针对深色主题的系统栏,可以先试试使用70%不透明度的黑色进行遮盖(可以在主题或者代码里进行设置-View.setStatusBarColor)

更多关于 SystemUI 方面的内容,可以参考Android Developer Guide界面篇,有更详细的解释。它详细地介绍了以下内容:

  • 概览
  • 调暗系统栏
  • 隐藏状态栏
    • 不同API下隐藏状态栏
    • 让内容显示在状态哦蓝后面
  • 隐藏导航栏
    • 不同API下隐藏导航栏
    • 让内容显示在导航栏后面
  • 启用全屏模式
    • 全屏选项
      • 向后倾斜
      • 沉浸模式
      • 粘性全屏模式
  • 响应界面可见度变更

处理视觉冲突 | 手势导航(二)

上个部分介绍了如何将应用构建到全面屏设备,然而有些交互可能导致应用的某些视图被系统栏覆盖,导致用户无法看见或者操作。这一部分正是为了解决这个问题而撰写—如何判断安全的交互区域。

边衬区 (Insets)

Thanks

Google Dev:开启全面屏体验|手势导航(一)
处理手势导航二
SystemUI Flags详解及使用情景

CATALOG
  1. 1. 开启全面屏体验 | 手势导航(一)
    1. 1.1. 全面屏体验
      1. 1.1.1. 在导航栏后面绘制内容
      2. 1.1.2. 在状态栏后面绘制内容
    2. 1.2. 如何实现
      1. 1.2.1. 1.请求进行全面屏布局
    3. 1.3. 2.更改系统栏颜色
  2. 2. 处理视觉冲突 | 手势导航(二)
    1. 2.1. 边衬区 (Insets)
    2. 2.2. Thanks