专栏名称: Android_开发者
目录
相关文章推荐
51好读  ›  专栏  ›  Android_开发者

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

Android_开发者  · 掘金  · android  · 2019-11-28 02:21

正文

阅读 101

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

作者 / Chris Banes, Android 开发者关系团队工程师

我们将在近期为大家带来一个关于 "手势导航" 的系列连载,本文是连载的第二篇,如果您希望了解其他手势导航的话题,请持续关注我们。

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

更具体一点来说,本文主要处理与系统 UI 出现视觉重叠的问题。系统 UI 包括屏幕上由系统提供的所有 UI,例如导航栏和状态栏,另外它还包括诸如通知面板之类的内容。

边衬区 (Insets)

不少 Android 开发者看到边衬区 (insets) 往往会退避三舍,这个可能来源自他们在 Android Lollipop 时代试图在状态栏后面绘制 UI 的经历,而这个经历并不那么令人愉悦。我们甚至能看到在 StackOverflow 上有个一直热门的问题 就是关于这个的。

Insets 区域负责描述屏幕的哪些部分会与系统 UI 相交 (intersect),例如导航或状态栏。如果您的控件出现在了这些区域内,就可能被系统 UI 遮盖。自然,我们可以使用 insets 区域来尝试解决视觉冲突,如把视图从屏幕边缘向内移动到一个合适的位置。

在 Android 上,Insets 区域由 WindowInsets 类表示,在 AndroidX 中则使用 WindowInsetsCompat。在 Android 10 系统中处理应用布局时,开发者需要知晓 5 个获取 insets 区域的方法。需要使用哪种方法取决于具体情况,接下来就让我们逐一说明。

系统窗口边衬区

方法: getSystemWindowInsets()

系统窗口区域是最常用到的。自 API 1 以来,它们就以各种形式存在着,并且每当系统 UI 重叠显示在您的应用上方时,这个方法就会被调用。常见的例子是下拉状态栏和导航栏,或者弹出屏幕软键盘 (IME)。

我们来看一个使用系统窗口区域的例子。我们有一个悬浮操作按钮 (FAB),它位于屏幕右下角,距离屏幕边缘 16dp (这符合 设计指南 中的要求)。

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:layout_margin="16dp"
    android:layout_gravity="bottom|end" />
复制代码

Google I/O 的官方应用中就有这种 FAB,在应用被迭代为全屏应用前它看起来是这个样子:

在迭代为全面屏应用后,为了取得更加沉浸式的体验,我们将日程表控件延展进了导航栏的区域。但这时可以看到 FAB 被导航栏遮住了:

更糟的是,FAB 现在被遮盖了,就意味着用户可能无法点击它。显然我们要解决这种视觉冲突。当系统设置为使用按钮导航模式时 (即上图例子所示),视觉冲突会更加明显,因为这时导航栏的高度更大。在系统使用手势导航模式时 (即导航栏变成屏幕底部的一条粗线,也就是导航条),由于导航条有动态色彩调整功能,这个冲突可能不会那么明显。但是请记住,系统 UI 可以随时切换为半透明遮盖模式,所以我们有必要彻底解决这个问题。

再强调一次,您现在最好在所有的导航模式下测试您的应用。

那么我们如何处理这种视觉冲突呢?系统窗口区域在这就能派上用场。这套 insets 描述了系统栏占据的区域,方便您使用对应的数值将自己的控件从系统栏下面移开。

具体到本例中,FAB 位于底部右侧边缘附近,因此我们可以使用 systemWindowInsets.bottom 和 systemWindowInsets.right 值来增加 FAB 下方和右方的边距。

增加边距后看到的效果如下:

本文后面会为大家介绍具体做法。

简而言之,系统窗口区域 insets 最适合那些需要点击的控件,可以确保系统栏不遮盖住它们。

可点击区域

方法: getTappableElementInsets()

接下来是 Android 10 中新增的可点击区域 insets。它们与上面的系统窗口区域 insets 非常相似。可点击区域 insets 用来界定可触发系统点击行为 (tap) 的最小区域。注意,使用可点击区域里的数值进行布局时,依然可能导致自己的控件与系统 UI 在视觉上重叠,这一点与系统窗口区域 insets 不同,使用后者的值对自己的控件进行位移后能确保不会与系统/导航栏发生视觉重叠。

这里让我们仍然使用 FAB 来举例:

注意看上图,在导航栏模式下,FAB 不会进入导航栏占据的高度 (48dp)。在手势操作 (导航条) 模式,且开启了导航条色彩适应后,虽然导航条依然有高度 (即红色区域 16dp),但它被认为是 "透明" 的,系统在这 16 dp 的高度内依然允许用户点击应用里的控件,所以在可点击区域 insets 中,其 bottom 值为 0dp。如上图所示,FAB 这时会更靠下一些。







请到「今天看啥」查看全文