概述:
提供全范围访问APP的一种方式就是使用逐级导航. 这里将会讨论”后代导航”(descendant navigation), 它可以让用户进入到一个子屏幕; 还有”横向导航”(lateralnavigation), 可以让用户访问相邻屏幕.
有两种相邻的屏幕: collection-related和section-related. collection-related表示它们之间是集合关系. section-related表示关于parent的不同部分的信息. 比如, 一个section可以用来展示一个object的文本信息, 另一个则用来提供对象地理位置的地图. 通常section-related的数量都不多.
后代导航和横向导航可以通过list, tab, 和其他的用户接口模型来实现. 用户接口模型, 很像软件设计模型, 用来解决常见的交互问题. 这里讲讨论一些横向导航模式.
按键和简单目标:
对于section-related屏幕, 在parent中提供可点击和支持键盘焦点的目标是在可点击屏幕中最常用的导航接口了. 这种类型的目标的典型栗子包括按键, 固定尺寸的列表view, 或者文字链接(尽管对于点击导航方式它不是一个理想的UI). 选择这些目标之一, 可以打开一个子屏幕, 代替当前的context. 按键和这些简单目标很少用于代表一个集合条目. 下图是基于按钮的导航的栗子, 以及仪表盘模式的按钮:
一种常见的访问顶层(top-level)APP section的按键模式是仪表盘模式(dashboard pattern). 仪表盘是一种摆在格子里的大图标按键, 它们构成了整体的或者大部分的parent. 根据顶层section的数目, 网格中通常有2~3行/列. 这种模型是展示APP中所有的section的一种很好的方法. 大型的点击目标也使得UI的使用变得很简单. 仪表盘的最佳使用场景是当每个section都同等重要的时候, 通常这由产品决定. 但是这种模式在大屏幕下视觉效果不算理想, 并且要求用户需要执行一个额外的步骤来跳转到APP的内容里.
更加复杂的用户界面可以利用其它的用户交互模式来提高内容的及时性和更加独特的呈现方式.
Lists,Grids, Carousels, and Stacks:
对于collection-related, 特别是文本信息, 垂直滚动列表是最长使用的接口了. 对于内容更加丰富或者媒体资源较多的条目, 如图片或者视频, 则可以使用垂直滚动的网格(Grid), 水平滚动的list(有时候被称为carousles(转盘)), 或者stack(有时被称作card(卡片))来代替. 这些UI元素通常最佳使用场景是用来展示集合中的条目或者一组子屏幕(比如新闻列表之类的), 而不是一小部分不相关的子屏幕.
这种模式有几个问题. 首先是深度问题, 基于列表的导航可以在点击时候引入更多的列表, 一层套一层, 经常会让列表看起来十分的繁琐. 需要访问某条内容变得麻烦, 需要点击多次, 这会让用户的使用变得十分低效, 体验不佳. 而且在大屏幕上经常留出很多空白, 因为它们通常都是固定高度, 并且宽度占满屏幕的. 解决方法包括在每个item中提供额外的信息或者使用多面板方案, 也就是列表和内容分开但是在同一个屏幕下显示.
Tabs:
在横向导航中, tab的使用十分常见. 这种模型将可滑动的屏幕分组, 通常用在条目比较少的(4个或者更少)section-related中.
Tab会穿过屏幕, 并且当选中的时候只有下面的内容区域会发生变化, 并且tab上面的标签应该一直保持可用. 另外, tab的切换不应该被保存在访问历史中. 比如用户从tab A切换到tab B, 那么当他点击返回键的时候, 不应该回到tab A. Tab通常是水平的, 但是其它的比如Action Bar中的下拉列表有时候也是可以接受的. 最后也是最重要的, tab应该总是在屏幕的顶部, 而不应该出现在底部.
使用基于list和button的导航时, tab可以带来明显的好处:
l 因为有一个单一并且已选中的tab,所以用户可以从parent直接访问该tab的内容.
l 用户可以在关联屏幕间快速导航, 不用再回到parent中.
注意, 在tab间切换的时候, 一定不能用模式dialog等阻塞tab页面的访问. 一个比较常见的对tab的批判是, 必须为tab的标签保留空间. 该问题通常是可以接受的. 可以通过自定义来优化这一点, 但是注意要留出空间来给用户点击. . .
水平页面(SwipeView):
另外一个著名的横向导航模式是水平页面, 也叫作swipe view. 该模式非常适用于collection-related相邻屏幕, 比如一个种类(商业, 技术, 健康等)的列表. 就像tab一样, 这个模式也支持用分组屏幕来展示子屏幕自己的layout的内容.
在水平页面UI中, 每次只能选择一个页面. 用户可以通过点击和滑动来导航到它的相邻屏幕. 这个交互方式通常需要另一个UI元素来辅助描述选中的页面以及可用页面, 可以提供更多上下文信息给用户. 这种情况十分必要. 这种辅助UI元素包括tabs, tick marks和scrolling labels:
如果子屏幕包含横向移动的平面(比如地图), 那么最好避免使用这种模式, 因为这时候横向滑动会发生滑动冲突, 让控件的可用性出现异常. 另外, 对于逻辑上是”兄弟关系”的屏幕, 水平页面是最合适的, 它们的内容类型相似, 并且这些子页面的数量相对较少. 这种情况下, 该模式可以跟tab一起非常直观的展示内容. 比如使用水平页面来表示连续的日历天数. 对于日历这类无限的集合, 特别是类似的在两个方向都有内容的情况, 这种分页机制可以工作的很好.
后退和向上导航:
现在用户可以导航到APP的很深入的层次, 我们就需要提供方法来向上层导航, 到”父屏幕”和”先祖屏幕”(父屏幕的父屏幕). 另外, 我们应该确保后退操作遵守Android的约定.
支持时空导航: 后退
时空导航, 或者在历史记录间导航, 在Android系统中已经沿用了很久. 所有的Android用户都期待后退按键可以将界面导航到前一个屏幕, 不管在什么状态. 历史记录的root应该在用户的桌面. 就是说, 点击后退按键足够的次数之后, 应该让我们回到桌面, 之后后退将不再实现任何功能.
APP通常不用担心管理后退键本身, 系统会处理任务和后台堆栈,或者自动列出前一个屏幕. 后退键默认情况下会简单的移除堆栈顶端的屏幕. 但是还是有一些我们可能需要重新定义后退键行为的情况. 比如, 如果屏幕包含了一个嵌入式web浏览器, 在浏览器中用户可以跟页面交互, 导航到前一个网页, 这时我们可能希望浏览器的后退键返回到前一个网页而不是默认行为. 在返回到最开始的页面后, 后退键应该执行它的默认行为.
支持”先祖导航”: Up和Home
Android3.0之前, 先祖导航最常见的形式是Home.一般会通过设备的Menu按键来实现这个操作, 或者在屏幕左上方的Home按键(通常作为Action Bar组件). 按下Home键的时候, 用户将会返回到屏幕堆栈的顶层, 一般是APP的Home屏幕. 为用户提供直接导航到Home屏幕的操作可以便于用户操作. 不管他们在APP的任何位置, 如果他们在APP的导航中”迷路”了, 那么可以选择Home按键返回到他们熟悉的Home屏幕中.
Android 3.0引入了Up键, 它在Action Bar中作为一个Home键的替代品. 点击了Up之后, 用户应该回到parent屏幕. 这通常会导航到前一个屏幕(就像后退键那样), 但是有时候会有例外的情况.因此开发者必须确保每个屏幕的Up操作都导航到唯一确定的parent屏幕中. 下图是Up导航行为的栗子, 这个操作跟Windows桌面系统有点相似.
在某些情况下, 使用Up执行某个操作而不是导航到parent屏幕也是合理的. 栗如, 在平板版本的基于Android 3.0的Gmail APP. 当在横屏的时候查看一个邮件会话的会话列表, 旁边则是会话详情. 然而在竖屏下查看邮件会话的时候, 只会显示会话详情. 这时Up键可以用来临时显示邮件列表的版面, 从屏幕的左侧划出. 当左侧的列表出现的时候, 再次点击Up键, 则会回到全屏的邮件会话列表.
注意, 如果想要获得最好的用户体验, 应该在实现Home或者Up键的时候确保清除之前屏幕的堆栈. 对于Home, 唯一保存在堆栈中的屏幕应该是home屏幕. 对于Up导航, 当前屏幕应该从堆栈中移除, 除非后退导航” across screen hierarchies”. 我们可以使用FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASKintent flag来实现它.
参考: https://developer.android.com/training/design-navigation/ancestral-temporal.html
https://developer.android.com/training/design-navigation/descendant-lateral.html