page.title=使用返回和向上导航 page.tags="navigation","activity","task","up navigation","back navigation" page.image=/design/media/navigation_between_siblings_gmail.png @jd:body <a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html"> <div> <h3>开发者文档</h3> <p>实现有效导航</p> </div> </a> <p itemprop="description">一致的导航操作是整体用户体验的重要组成部分。如果基本的导航方法都不能保持一致,甚至让用户意想不到的话,恐怕没有比这更让人沮丧的事情了。 Android 3.0对全局导航行为做出了重大改变。 对用户来说,认真遵照“返回”和“向上”的指导准则可让应用的导航更可靠、更符合预期。 </p> <p>Android 2.3 及更早的版本使用系统<em>返回</em>按钮来支持应用内的导航。 在 Android 3.0 中引入操作栏后,出现了第二种导航机制:即<em>向上</em>按钮,由应用图标和左向箭头构成。 </p> <img src="{@docRoot}design/media/navigation_with_back_and_up.png"> <h2 id="up-vs-back">向上与返回的比较</h2> <p>“向上”按钮用于根据屏幕之间的层级关系在某个应用内部导航。 例如,如果屏幕 A 显示项目列表,并且选择某个项目会调出屏幕 B(该屏幕显示项目的更多详情),则屏幕 B 应提供可返回屏幕 A 的“向上”按钮。 </p> <p>如果屏幕是应用中层级最高的屏幕(即应用的主屏幕),则无需提供向上按钮。 </p> <p>系统的“返回”按钮用于按照用户最近操作的屏幕历史记录,按时间逆序导航。 它通常基于屏幕之间的时间关系,而非应用的层级关系。 </p> <p>如果之前查看的屏幕也是当前屏幕的父级项,按下“返回”按钮的作用跟按下“向上”按钮一样 — 这种情况很常见。 但是,“向上”按钮可确保用户留在应用内,与此不同的是,“返回”按钮可让用户返回到主屏幕,甚至返回不同的应用。 </p> <img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png"> <p>“返回”按钮还支持与屏幕间导航并无直接关联的一些行为: </p> <ul> <li>清除浮动窗口(对话框、弹出窗口)</li> <li>清除上下文操作栏,并取消高亮显示所选项目</li> <li>隐藏屏幕键盘 (IME)</li> </ul> <h2 id="within-app">应用内导航</h2> <h4>通过多个入口点导航屏幕</h4> <p>有时,某个屏幕在应用层级中的位置并不固定,可以从多个入口点抵达 — 例如可从应用中的其他任何屏幕抵达设置屏幕。 在这种情况下,应选择“向上”按钮来返回到引用屏幕,其行为跟“返回”按钮相同。 </p> <h4>更改屏幕中的视图</h4> <p>更改屏幕的视图选项不会更改“向上”或“返回”的行为:屏幕仍然位于应用层级中的同一位置,并且不会创建新的导航历史记录。 </p> <p>此类视图更改的示例包括:</p> <ul> <li>使用选项卡和/或左右滑动切换视图</li> <li>使用下拉菜单(即折叠的选项卡)切换视图</li> <li>筛选列表</li> <li>列表排序</li> <li>更改显示特性(例如缩放)</li> </ul> <h4>在同级屏幕之间导航</h4> <p>如果您的应用支持从项目列表导航至其中某个项目的详情视图,通常最好支持从该项目导航到列表中该项目之前或之后的另一项目。 例如,在 Gmail 中,只需在会话中向左或向右滑动,即可轻松查看同一收件箱中较新或较旧的会话。 在某个屏幕内更改视图这样的导航不会改变“向上”或“返回”的行为。 </p> <img src="{@docRoot}design/media/navigation_between_siblings_gmail.png"> <p>然而,当在多个彼此相关、但并未通过引用列表绑定在一起的详情视图之间浏览时,例如,在 Play 商店中同一开发商开发的多款应用或者同一艺术家推出的多张专辑之间切换浏览时,会发生值得注意的例外情况。 在这些情况下,跟踪每个链接不会创建历史记录,这就导致点击“返回”按钮时会逐一显示之前查看过的每个屏幕。 点击“向上”按钮则会直接绕过这些相关的屏幕并导航至最近查看的容器屏幕。 </p> <img src="{@docRoot}design/media/navigation_between_siblings_market1.png"> <p>您可以根据详情视图的实际情况让“向上”按钮的行为更加智能。 将上述 Play 商店示例进一步展开,设想用户从查看过的上一本图书导航至电影改编详情。 在这种情况下,“向上”按钮可返回至用户之前导航时未经历过的容器(电影)。 </p> <img src="{@docRoot}design/media/navigation_between_siblings_market2.png"> <h2 id="into-your-app">通过主屏幕小工具和通知进入您的应用</h2> <p>使用主屏幕小工具或通知,您可以帮助用户直接导航至应用中的深层屏幕。 例如,Gmail 的收件箱小工具和新消息通知都可绕过收件箱屏幕,让用户直接进入会话视图。 </p> <p>对于这两种情况,请按下述说明处理“向上”按钮:</p> <ul> <li><em>如果目的屏幕通常通过应用</em>中的某个特定屏幕抵达,“向上”按钮应导航至该屏幕。 </li> <li><em>否则</em>,“向上”按钮应导航至应用的顶级屏幕(“主屏幕”)。</li> </ul> <p>对于“返回”按钮,您应将指向应用顶级屏幕的完整向上导航路径插入到任务的返回栈,从而让导航更具预见性。 这样,如果用户忘记了之前是如何进入您的应用的,则可以在退出之前导航至应用的顶级屏幕。 </p> <p>例如,Gmail 的主屏幕小工具有一个按钮可以让您直接进入写邮件屏幕。 在写邮件屏幕上使用“向上”或“返回”可让用户进入“收件箱”,而在收件箱屏幕上使用“返回”则可回到主屏幕。 </p> <img src="{@docRoot}design/media/navigation_from_outside_back.png"> <h4>间接通知</h4> <p>如果您的应用需要同时提供关于多个事件的信息,可使用一条通知将用户引导至某个间隙屏幕。 该屏幕将这些事件汇总,并为用户提供深度导航应用的路径。 这种样式的通知称为<em>间接通知</em>。 </p> <p>与标准(直接)通知不同,在间接通知的间隙屏幕上按下“返回”会让用户回到触发通知的点 — 不会在返回栈中插入额外的屏幕。 一旦用户从应用的间隙屏幕进入应用的更深层级,则“向上”和“返回”按钮的行为就与用于标准通知时相同,如上所述:在应用内部导航,而非返回至间隙屏幕。 </p> <p>例如,假设 Gmail 中的用户收到来自日历的间接通知。触摸该通知会打开间隙屏幕,该屏幕会显示数个不同事件的提醒。 在间隙屏幕上触摸“返回”会让用户回到 Gmail。触摸特定事件会让用户离开间隙屏幕并进入完整的日历应用,以显示事件的详情。 在事件详情屏幕上,使用“向上”和“返回”可导航至日历的顶级视图。</p> <img src="{@docRoot}design/media/navigation_indirect_notification.png"> <h4>弹出通知</h4> <p><em>弹出通知</em>会绕过抽屉式通知栏,直接显示在用户面前。 一般很少使用这种通知,<strong>仅在需要即时响应并且有必要中断用户当前操作时使用</strong>。 例如,Talk 使用这种方式来提醒用户收到了好友加入视频聊天的邀请,因为该邀请将在几秒之后自动过期。 </p> <p>从导航行为的角度来看,弹出通知会密切跟踪间接通知的间隙屏幕的行为。 使用“返回”会清除弹出通知。如果用户从弹出通知导航至通知应用中,则“向上”和“返回”会依照标准通知的规则在应用内导航。 </p> <img src="{@docRoot}design/media/navigation_popup_notification.png"> <h2 id="between-apps">在应用之间导航</h2> <p>Android 系统的一个基本优势在于能够让应用相互激活,这样用户就可以直接从一个应用导航到另一个应用。 例如,需要获取照片的应用可激活相机应用,后者可将照片返回给前者。 这对于开发者和用户来说都极为有利,开发者可以方便地利用来自其他应用的代码,而用户则在执行常用操作时可以获得一致的体验。 </p> <p>为了理解应用到应用的导航,必须理解下面探讨的 Android 框架行为。 </p> <h4>Activity、任务和 Intent</h4> <p>在 Android 中,<strong>Activity</strong> 是一个应用组件,用于定义信息屏幕以及用户可执行的所有相关操作。 您的应用是 Activity 的集合,由您创建的 Activity 以及从其他应用重用的 Activity 构成。 </p> <p><strong>任务</strong>是用户为达成某个目标而执行的 Activity 序列。一个 任务可以只利用一个应用的 Activity,也可以利用来自多个不同应用的 Activity。 </p> <p><strong>Intent</strong>是应用的一种机制,用于发出信号以表明需要另一个应用的辅助才能执行某个操作。 应用的 Activity 可指示其可响应哪些 Intent。 对于诸如“分享”这样的常用Intent,用户可能安装有许多可执行该请求的应用。 </p> <h4>示例:在应用之间导航以支持分享</h4> <p>要了解如何结合使用 Activity、任务和 Intent,可以考虑如何让一个应用允许用户通过使用另一应用来分享内容的例子。 例如,从主屏幕启动 Play 商店应用可启动新任务 A(参见下图)。 在 Play 商店中导航并触摸某本促销图书来查看其详情之后,用户会停留在该任务中并通过添加 Activity 来扩展该任务。 触发“分享”操作会通过一个对话框来提示用户选择 Activity,该对话框中会列出来自不同应用、之前已注册用于处理“分享” Intent 的每一种 Activity。 </p> <img src="{@docRoot}design/media/navigation_between_apps_inward.png"> <p>如果用户选择通过 Gmail 分享,则会以延续任务 A 的形式添加 Gmail 的写邮件 Activity — 而不会创建新任务。 如果 Gmail 在后台还运行有自己的任务,该任务不会受影响。 </p> <p>在写邮件 Activity 中,发送邮件或触摸“返回”按钮会让用户回到图书详情 Activity。 之后继续触摸“返回”会在 Play 商店中继续回退,直至抵达主屏幕。 </p> <img src="{@docRoot}design/media/navigation_between_apps_back.png"> <p>尽管如此,用户可通过在写邮件 Activity 中触摸“向上”按钮表明其希望留在 Gmail 中。 此时会显示 Gmail 的会话列表 Activity,并为其创建新任务 B。新任务都始于主屏幕,因此从会话列表触摸“返回”按钮,始终会回到主屏幕。 </p> <img src="{@docRoot}design/media/navigation_between_apps_up.png"> <p>任务 A 保持在后台运行,用户可稍后回到该任务(例如通过“最近使用的应用”屏幕)。 如果 Gmail 在后台还运行有自己的任务,该任务会被任务 B 取代 — 之前的上下文会被丢弃,以使用户达成新目标。 </p> <p>如果您的应用经过注册,以使用应用中的深层 Activity 来处理 Intent,可参阅<a href="#into-your-app">通过主屏幕小工具和通知进入您的应用</a>,获得有关如何指定“向上”导航行为的指导。 </p>