当前位置: 首页 > news >正文

Google 发布的全新导航库:Jetpack Navigation 3

前言

多年来,Jetpack Navigation 库一直是开发者的重要工具,但随着 Android 用户界面领域的发展,特别是大屏设备的出现和 Jetpack Compose 的兴起,Navigation 的功能也需要与时俱进。 今年的 Google I/O 上重点介绍了 Jetpack Navigation 3,这是一个专门为 Compose 全新打造的导航库,简称 Nav3。

为何需要新的导航库?

最初的 Jetpack Navigation 库(有时被称为 Nav2,因为它的主版本号是 2 )早在 2018 年就发布了,那时 AndroidX 和 Compose 都还未出现。尽管它很好地实现了最初的目标,但大家反馈说,在与现代 Compose 模式配合使用时,它存在一些局限性。

问题一:返回栈状态只能间接观察。

在原有的 Jetpack Navigation 库(Nav2 )中,开发者不能直接获取返回栈当前的状态信息。比如,不能直接得知当前栈里有哪些目的地、栈顶是哪个目的地等。而是需要通过一些间接的方式,像设置监听器,在某些事件触发时(比如有新的目的地入栈、出栈等)才能获取到部分相关信息,这种间接获取的方式不够直观和便捷。

问题二:可能存在两个数据源,这可能会导致应用状态不一致。

由于问题一的存在,很多开发者会在自己维护与返回栈相关的状态信息。一方面库自身内部维护了一份返回栈状态,另一方面开发者可能在应用代码里通过一些逻辑也记录了返回栈相关状态(比如自己记录了当前显示的是哪个页面 )。这就相当于有两个地方在记录同一件事(返回栈状态 )。由于有两个数据源,它们可能会因为各种原因(比如库内部更新了返回栈状态,但开发者自己维护的那份没及时更新 ,或者反过来 )出现状态不一致的情况。

在这里插入图片描述

问题三:Nav2 的 NavHost 设计为仅显示单个目的地

返回目的只能是栈中最顶层的那个,这使得实现能同时显示多个内容窗格的自适应布局变得困难,比如在大屏幕设备上同时展示多个页面(列表+详情页):

在这里插入图片描述

Nav3 的基本思想

Nav3 基于旨在提供更大灵活性和开发者控制权的原则构建:

  • 自定义目标类型:开发者,而非库,拥有并控制返回栈。它是一个由 Compose 状态支持的简单列表。具体来说,Nav3 要求返回栈为 SnapshotStateList<T> ,其中 T 可以是你选择的任何类型。你可以通过添加或删除元素(T 类型)来进行导航,状态变化会通过 Nav3 驱动用户界面变化。

  • 开放透明:广大开发者不希望导航库是一个内部组件和状态无法访问的黑箱。Nav3 被设计为开放且可扩展的,提供构建模块和实用的默认设置。如果我们想要自定义导航行为,可以深入底层,创建自己的组件和自定义设置。

  • 选择构建模块:Nav3 不将所有行为都嵌入库中,而是提供较小的组件,我们可以将它们组合起来创建更复杂的功能。

添加预测返回动画和目标跳转动画的效果
在这里插入图片描述

Nav3 关键特性

  • 动画:为目的地的切换提供了内置的过渡动画,包括预测返回动画。它还拥有灵活的 API 用于自定义动画行为,允许在应用和单个屏幕层面覆盖动画设置。

  • 自适应布局:一个灵活的布局 API(名为 Scenes )允许你在同一布局中渲染多个目的地(例如,在大屏幕设备上的列表 - 详情布局)。这使得在单窗格和多窗格布局之间切换变得容易。

  • 状态作用域:能够将状态限定在返回栈的目的地中,包括通过专用的 Jetpack 生命周期库对 ViewModel 提供可选支持。

  • 模块化:API 设计允许将导航代码拆分到多个模块中。这缩短了构建时间,并实现了功能模块之间清晰的职责分离。

代码示例

最后通过一小段代码片段,管中窥斑 Nav3 如何工作:

// Define the routes in your app and any arguments.
data object Home
data class Product(val id: String)// Create a back stack, specifying the route the app should start with.
val backStack = remember { mutableStateListOf<Any>(Home) }// A NavDisplay displays your back stack. Whenever the back stack changes, the display updates.
NavDisplay(backStack = backStack,// Specify what should happen when the user goes backonBack = { backStack.removeLastOrNull() },// An entry provider converts a route into a NavEntry which contains the content for that route.entryProvider = { route ->when (route) {is Home -> NavEntry(route) {Column {Text("Welcome to Nav3")Button(onClick = {// To navigate to a new route, just add that route to the back stackbackStack.add(Product("123"))}) {Text("Click to navigate")}}}is Product -> NavEntry(route) {Text("Product ${route.id} ")}else -> NavEntry(Unit) { Text("Unknown route: $route") }}}
)

参考资料

  • 官方文档:https://developer.android.com/guide/navigation/navigation-3?hl=zh-cn

  • 官方示例:https://github.com/android/nav3-recipes

官方示例中可以看到很多常见导航组件如何与 Nav3 配合,例如 Navigation Bar, Navigation Rail 等,另外也有一个 Login 的例子展示一个 Nav3 的具体业务场景;此外也可以看到使用 Scene 的自定义布局实例

http://www.lqws.cn/news/79687.html

相关文章:

  • 【深度学习新浪潮】以Dify为例的大模型平台的对比分析
  • 【算法】分支限界
  • Python库CloudScraper详细使用(绕过 Cloudflare 的反机器人页面的 Python 模块)
  • 《Pytorch深度学习实践》ch3-反向传播
  • 数字化转型全场景安全解析:从产品到管理的防线构建与实施要点
  • 自适应流量调度用于遥操作:面向时间敏感网络的通信与控制协同优化框架
  • 用wireshark抓包分析学习USB协议
  • 04powerbi-度量值-筛选引擎CALCULATE()
  • 吴恩达MCP课程(5):research_server_prompt_resource.py
  • 光伏功率预测 | BiLSTM多变量单步光伏功率预测(Matlab完整源码和数据)
  • HTML 等价字符引用:系统化记忆指南
  • 网络攻防技术五:网络扫描技术
  • Linux中的mysql逻辑备份与恢复
  • 二叉树的层序遍历与完全二叉树判断
  • HarmonyOS鸿蒙Taro跨端框架
  • 已有的前端项目打包到tauri运行(windows)
  • AI智能体|扣子(Coze)搭建【合同/文档审查】工作流
  • SpringBoot手动实现流式输出方案整理以及SSE规范输出详解
  • 从 LeetCode 到日志匹配:一行 Swift 实现规则识别
  • 【Godot】如何导出 Release 版本的安卓项目
  • Linux服务器安装GUI界面工具
  • Grafana对接Prometheus数据源
  • LlamaIndex的IngestionPipeline添加本地存储(本地文档存储)
  • 【深度学习】实验四 卷积神经网络CNN
  • 记录一次由打扑克牌测试国内各家大模型的经历
  • 2025年5月24日系统架构设计师考试题目回顾
  • 使用 OpenCV (C++) 进行人脸边缘提取
  • 大数据-275 Spark MLib - 基础介绍 机器学习算法 集成学习 随机森林 Bagging Boosting
  • shiro使用详解
  • Java后端优化:对象池模式解决高频ObjectMapper实例化问题及性能影响