android Navigation3

98 阅读5分钟

当前时间是预发布版本

可阅读官方博文

以下内容是一键翻译出来,可能有不合理的地方。

由开发者关系工程师 Don Turner 发布 

在应用中切换屏幕应该很简单,对吧?然而,构建一个强大、可扩展且令人愉悦的导航体验却并非易事。多年来,Jetpack Navigation 库一直是开发者的重要工具,但随着 Android UI 格局的演变,特别是 Jetpack Compose 的兴起,我们意识到需要一种新的方法。

今天,我们很高兴地推出Jetpack Navigation 3,这是一个专为 Compose 从零开始构建的全新导航库。为了简洁起见,我们之后将简称其为 Nav3。该库以声明式编程模型Compose 状态为基本构建模块。

为什么要建立一个新的导航库?

最初的 Jetpack Navigation 库(有时也称为 Nav2,因为它已更新到主要版本 2)最初于 2018 年发布,早于 AndroidX 和 Compose。虽然它很好地实现了最初的目标,但我们收到用户反馈,它在处理现代 Compose 模式时存在一些局限性。

一个关键的限制是,返回栈的状态只能间接观察。这意味着可能存在两个不同的数据源,从而导致应用程序状态不一致。此外,Nav2 的NavHost被设计成只能显示单个目标页面——即返回栈顶部的目标页面——并填充可用空间。这使得实现能够同时显示多个内容窗格的自适应布局变得困难,例如在大屏幕上显示列表详情布局。

单窗格和双窗格布局的图示,分别展示了列表和详细信息功能

图 1. 从单窗格布局更改为多窗格布局可能会带来导航挑战

创始原则

Nav3 的设计理念旨在提供更大的灵活性和开发者控制权:

    • 返回栈由您掌控: 您(开发者)而非库拥有并控制返回栈。它是一个简单的列表,由 Compose 状态提供支持。具体来说,Nav3 要求您的返回栈是SnapshotStateList类型,其中T可以是您选择的任何类型。您可以通过添加或删除项(T)来进行导航,状态更改会被 Nav3 的 UI 观察并反映出来。
    • 别再阻碍我们了: 我们了解到您不喜欢导航库像个黑盒子,内部组件和状态难以访问。Nav3 的设计理念是开放且可扩展的,它为您提供构建模块和实用的默认设置。如果您需要自定义导航行为,可以深入到更底层,创建自己的组件和自定义项。
    • 选择你的构建模块:  Nav3 并没有将所有行为都嵌入库中,而是提供了更小的组件,你可以将它们组合起来创建更复杂的功能。我们还提供了一本“配方手册”,展示了如何组合组件来解决常见的导航难题。

图示 Nav3 显示屏如何观察开发者拥有的返回栈的变化

图 2.  Nav3 显示器观察开发者拥有的返回栈的变化。

主要特点

    • 自适应布局: 灵活的布局 API(名为“场景”)允许您在同一布局中渲染多个目标页面(例如,在大屏幕设备上使用列表详情布局)。这使得在单窗格布局和多窗格布局之间切换变得容易。
    • 模块化:  API 设计允许将导航代码拆分到多个模块中。这不仅缩短了构建时间,还实现了功能模块之间职责的清晰分离。
    • 动态图像演示移动设备上的自定义动画和预测性返回功能

    • 图 3. 自定义动画和预测返回很容易实现,也很容易针对各个目的地进行覆盖。

    • 基本代码示例

    • 为了让您了解 Nav3 的工作原理,这里有一个简短的代码示例。

    • // 定义应用中的路由和任何参数。
      数据对象Home
      数据类Product ( val id : String )   
      
      // 创建一个返回栈,指定应用程序应该从哪个路由开始。val backStack = remember { mutableStateListOf < Any > ( Home ) }
       
      
      // NavDisplay显示你的返回栈。每当返回栈发生变化时,显示都会更新。NavDisplay ( 
          backStack = backStack ,
      
      
          //指定用户返回时应该发生的情况
          onBack = { backStack.removeLastOrNull ( ) },  
      
          
          // 入口提供程序将路由转换为包含该路由内容的 NavEntry。entryProvider = { route -> when ( route ) { is Home -> NavEntry ( route ) { Column { Text ( "欢迎使用 Nav3" ) Button ( onClick = { // 要导航到新路由,只需将该路由添加到返回栈
                              backStack . add ( Product ( "123" )) }) { Text ( "点击导航" ) } } } is Product -> NavEntry ( route ) { Text ( "产品 ${route.id} " ) } else -> NavEntry ( Unit ) { Text ( "未知路由:$route" ) } } } ) 
                
                      
                       
                          
                           
                              
                           
                              
                          
                      
                  
                      
                      
                  
                       
              
          
      
    • 开始并提供反馈

    • 首先,请查看开发者文档以及提供示例的配方库:

        • 常见的导航用户界面,例如导航栏或导航条。
        • 条件导航,例如登录流程
        • 使用场景的自定义布局
    • 我们计划未来针对更复杂的用例提供代码示例、文档和博客。

    • Nav3 目前处于 alpha 测试阶段,这意味着 API 可能会根据用户反馈进行更改。如果您遇到任何问题或想提供反馈,请提交 issue

    • Nav3 为在 Compose 应用中构建现代导航提供了灵活而强大的基础。我们非常期待看到您用它创造出什么。

    • 从 5 月 22 日起,您可以在io.google上查看此公告以及所有 Google I/O 2025 的更新。