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

article/2025/7/13 9:43:43

前言

多年来,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.hkcw.cn/article/OHcldvKaxu.shtml

相关文章

抖音商城抓包 分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 抓包展示 总结 1.出于安全考虑,本章未…

uniapp-商城-77-shop(8.2-商品列表,地址信息添加,级联选择器picker)

地址信息,在我们支付订单上有这样一个接口,就是物流方式,一个自提,我们就显示商家地址。一个是外送,就是用户自己填写的地址。 这里先说说用户的地址添加。需要使用到的一些方式方法,主要有关于地址选择器,就是uni-data-picker级联选择。 该文介绍了电商应用中地址信息处…

AlmaLinux OS 10 正式发布:兼容 RHEL 10 带来多项技术革新

AlmaLinux OS 基金会日前宣布推出 AlmaLinux OS 10&#xff0c;该版本代号代号紫色的狮子 (Purple Lion)&#xff0c;新版本带来多项新功能和技术更新&#xff0c;旨在为用户提供更强大的企业级 Linux 体验。 该系统使用与 RHEL 10 相同的源代码构建并于 RHEL 10 保持完全兼…

深入理解C# MVVM模式:从理论到实践

在现代软件开发中&#xff0c;良好的架构设计对于构建可维护、可测试和可扩展的应用程序至关重要。Model-View-ViewModel (MVVM) 是一种特别适合XAML-based应用程序&#xff08;如WPF、Xamarin和UWP&#xff09;的架构模式。本文将全面探讨MVVM模式的概念、实现细节、最佳实践以…

Git GitHub Gitee

一、Git 是一个免费、开源的分布式版本控制系统。 版本控制&#xff1a;一种记录文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。它最重要的就是可以记录文件修改历史记录&#xff0c;从而让用户可以看历史版本&#xff0c;方便版本切换。 1.和集中式版本控制…

数据库管理-第332期 大数据已死,那什么当立?(20250602)

数据库管理332期 2025-06-02 数据库管理-第332期 大数据已死&#xff0c;那什么当立&#xff1f;&#xff08;20250602&#xff09;1 概念还是技术2 必然的大数据量3 离线到实时4 未来总结 数据库管理-第332期 大数据已死&#xff0c;那什么当立&#xff1f;&#xff08;202506…

Java Netty 中处理粘包和半包问题的解决方案 | TCP消息完整性校验(XOR )

文章目录 引言I 处理TCP粘包和半包问题背景粘包问题的产生原因解决方案WebSocket中的粘包和半包问题及解决方案II Java Netty 中处理粘包和半包问题粘包和半包问题可以通过以下几种方式解决:使用分隔符解码器基于长度字段的解码器实现自定义解码器III TCP常见封装处理消息接收…

鸿蒙next系统以后会取代安卓吗?

点击上方关注 “终端研发部” 设为“星标”&#xff0c;和你一起掌握更多数据库知识 官方可没说过取代谁谁&#xff0c;三足鼎立不好吗&#xff1f;三分天下&#xff0c;并立共存。 鸿蒙基于Linux&#xff0c;有人说套壳&#xff1b;ios/macos基于Unix&#xff0c;说它ios开源了…

排便不是一件可以随意“延后”的事:长期便秘->直肠敏感性降低->功能性便秘->大便失禁

文章目录 引言知识扩展: 快乐排便的黄金姿势I 便秘并不是一种单一成因的疾病便秘成因临床治疗II 总是压抑排便,身体会发生的变化III 排便不是一件可以随意“延后”的事引言 排便是一种复杂的反射行为: 由“直肠充盈—产生便意—括约肌协调—排出”的完整生理链条完成的。 …

基于Spring Boot 电商书城平台系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

Golang——5、函数详解、time包及日期函数

函数详解、time包及日期函数 1、函数1.1、函数定义1.2、函数参数1.3、函数返回值1.4、函数类型与变量1.5、函数作参数和返回值1.6、匿名函数、函数递归和闭包1.7、defer语句1.8、panic和recover 2、time包以及日期函数2.1、time.Now()获取当前时间2.2、Format方法格式化输出日期…

HTTP详解

使用的工具&#xff1a;fiddler 一、请求和响应报文的结构 1.请求 ⾸⾏: [⽅法] [url] [版本]Header: 请求的属性, 冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束Body: 空⾏后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有…

解决:install via Git URL失败的问题

为解决install via Git URL失败的问题&#xff0c;修改安全等级security_level的config.ini文件&#xff0c;路径如下&#xff1a; 还要重启&#xff1a; 1.reset 2.F5刷新页面 3.关机服务器&#xff0c;再开机&#xff08;你也可以省略&#xff0c;试试&#xff09; 4.Wind…

【小工具开发】通过Java实现批量修改文件名小工具

1. 创建Project&#xff08;使用Gradle&#xff09; 2.安装Gradle 修改 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-8.12-bin.zip 修改 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-8.12-all.zip 阅读了以下博客&#xff0c;发…

【AI智能体】Spring AI MCP 从使用到操作实战详解

目录 一、前言 二、MCP 介绍 2.1 什么是MCP 2.2 MCP 核心特点 2.3 MCP 核心价值 2.4 MCP 与Function Calling 区别 三、Spring AI MCP 架构介绍 3.1 整体架构 3.1.1 三层架构实现说明 3.2 服务端与客户端 3.2.1 MCP 服务端 3.2.1 MCP 客户端 3.3 MCP中SSE和STDIO区…

Python打卡DAY43

复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 我选择ouIntel Image Classification | Kagglezz&#xff0c;该数据集分为六类&#xff0c;包含建筑、森林、冰川、山脉、海洋和街道…

香橙派3B学习笔记5:Linux文件系统分区_A/B系统分区

经过之前的多次分区失败导致系统重启无法进入&#xff0c;这次调整思路重新分区 ssh &#xff1a; orangepi本地ip 密码 &#xff1a; orangepi 操作系统发行版&#xff1a; 基于 Ubuntu 20.04.6 LTS&#xff08;Focal Fossa&#xff09;的定制版本&#xff0c;专门为 Orange …

第16讲、Odoo 18 序号(Sequence)详解

目录 序号系统概述底层实现原理常见序号规则使用方法与最佳实践案例分析&#xff1a;客户工单管理系统常见问题与解决方案总结 序号系统概述 Odoo 中的序号&#xff08;Sequence&#xff09;系统是一个用于生成唯一标识符的核心机制&#xff0c;主要用于为业务单据&#xff…

内存管理--《Hello C++ Wrold!》(8)--(C/C++)--深入剖析new和delete的使用和底层实现

文章目录 前言C/C内存分布new和deletenew和delete的底层定位new表达式 内存泄漏作业部分 前言 在C/C编程中&#xff0c;内存管理是理解程序运行机制的核心基础&#xff0c;也是开发高效、稳定程序的关键。无论是局部变量的存储、动态内存的分配&#xff0c;还是对象生命周期的…

Linux之进程间通信

目录 一、进程间通信介绍 1.1、进程间通信目的 1.2、进程间通信发展 1.3、进程间通讯分类 二、管道 三、匿名管道 3.1、示例代码 完整重定向问题&#xff1a; 3.2、⽤ fork 来共享管道原理 3.3、站在⽂件描述符⻆度-深度理解管道 3.4、站在内核⻆度-管道本质 3.5、…