Compose | UI组件(十四) | Navigation-Data - 页面导航传递数据
文章目录
- 前言
- 传参流程
- 实例说明
- 普通方式传值
- 定义接受参数格式
- 定义接受参数类型
- 获取参数
- 传入参数
- 传参和接受参数效果图
- 结合 ViewModel 传递参数
- 定义ViewModel
- 在 navigation 定义 ViewModel 实例,并且传入 LoginScreen
- 传入输入框中的值,并且跳转传值
- 获取值
- Parcelable 传递参数
- 定义一个数据类
- 自定义定义一个通用的NavType
- 设置一个接受参数的占位符
- 传递参数
- 接收参数
- 总结
前言
在 Compose 中使用 Navigation 组件进行页面跳转时,可以使用 NavController 和 NavHost 来传递参数。
传参流程
- 使用 NavController 传递参数:
NavController 是 Navigation 组件的核心类,用于控制页面导航。你可以在 NavController 中使用
navigate() 方法传递参数。这些参数可以在目标页面中通过参数名称获取并使用。
例如:
navController.navigate("SecondScreen") { // 传递参数 arguments = remember { mutableStateOf("key") } arguments?.putString("key", "value")
}
在目标页面中,可以通过 arguments 参数获取传递的参数:
val value = arguments?.getString("key") ?: "default value"
- 使用 NavHost 传递参数:
在 NavHost 中,可以使用 composable() 函数定义导航路径和参数。在 composable()
函数中,可以指定传递的参数和接收参数的方法。
例如:
NavHost(navController = navController, startDestination = "MainScreen") { composable("MainScreen") { MainScreen(arguments = listOf("value1", "value2")) } composable("SecondScreen") { SecondScreen(arguments = listOf("value3", "value4")) }
}
在目标页面中,可以通过 arguments 参数获取传递的参数:
val values = arguments[0] + arguments[1] // value1value2 for MainScreen, value3value4 for SecondScreen
这些是在 Compose 中使用 Navigation 组件进行参数传递的一些常见方法。具体实现可能因不同的平台、框架或技术而有所差异。
实例说明
下面使用登录页面传入用户名和密码,到详情页面,做为讲解案例
普通方式传值
就是通过 (状态)State 控制变量的传值
定义接受参数格式
object Detail:Screen(route = "$DETAIL?id={id},name={name},password={password}")
注:$DETAIL?id={id},name={name},password={password} 改为 $DETAIL/id={id},name={name},password={password}。将 ? 改为 / ,如果没有传值,程序就会崩溃,/ 默认是必填的,? 默认是选填的
定义接受参数类型
composable(route = Screen.Detail.route,arguments = listOf(navArgument(DETAIL_ARGUMENT_ID){type = NavType.IntTypedefaultValue = 0},navArgument(DETAIL_ARGUMENT_NAME){type = NavType.StringTypedefaultValue = "name is null"},navArgument(DETAIL_ARGUMENT_PASSWORD){type = NavType.StringTypedefaultValue = "password is null"})
)const val DETAIL_ARGUMENT_ID = "id"
const val DETAIL_ARGUMENT_NAME = "name"
const val DETAIL_ARGUMENT_PASSWORD = "password"
获取参数
composable(route = Screen.Detail.route,...){navBackStackEntry ->val id = navBackStackEntry.arguments?.getInt("id") ?: 0val name = navBackStackEntry.arguments?.getString("name") ?: ""val password = navBackStackEntry.arguments?.getString("password") ?: ""DetailScreen(id,name,password,navController = navController)
}
传入参数
object Detail:Screen(route = "..."){fun passIdAndName(id:Int= 0,name:String="tanZuAi",password:String="tanZuAi123"):String{return "$DETAIL?id=${id},name=${name},password=${password}"}
}navController.navigate(Screen.Detail.passIdAndName())
传参和接受参数效果图

至此,基本的传参,就已经可以实现了
结合 ViewModel 传递参数
就是通过结合 ViewModel 传参
定义ViewModel
LoginViewModel.kt
class LoginViewModel: ViewModel(){var nameText by mutableStateOf("")fun onTextChanged(newString:String){nameText = newString}
}
在 navigation 定义 ViewModel 实例,并且传入 LoginScreen
navigation(startDestination = Screen.Login.route,route = AUTHENTICATION_ROUTE){composable(route = Screen.Login.route){val loginViewModel = viewModel<LoginViewModel>()LoginScreen(loginViewModel,navController = navController)}composable(route = Screen.Signup.route){SignUpScreen(navController = navController)}
}
传入输入框中的值,并且跳转传值
LoginScreen.kt
//定义ViewModel 参数
fun LoginScreen(loginViewModel:LoginViewModel = viewModel(), navController: NavController)//注释掉状态定义的变量值
//var textName by remember { mutableStateOf("") }
//监听输入框的值,并且改变viewmodel变量的值
OutlinedTextField(value = loginViewModel.nameText,onValueChange = {loginViewModel.onTextChanged(it)},label = { Text(text = stringResource(id = R.string.app_user_name)) },modifier = Modifier.fillMaxWidth()
)//传值给name
navController.navigate(Screen.Detail.passIdAndName(name = loginViewModel.nameText))
获取值
Screen.kt
object Detail:Screen(route = "$DETAIL?id={id},name={name},password={password}"){fun passIdAndName(id:Int= 0,name:String="tanZuAi",password:String="tanZuAi123"):String{return "$DETAIL?id=${id},name=${name},password=${password}"}
}
HomeNavGraph.kt
val name = navBackStackEntry.arguments?.getString("name") ?: ""DetailScreen(id,name,password,navController = navController)
DetailScreen.kt
Text(modifier = Modifier.clickable {},text = "Detail_Name: $name" ,color = Color.Red,style = MaterialTheme.typography.bodyLarge)
至此,结合 ViewModel 传值流程已经讲完了
Parcelable 传递参数
通过Parcelable传递一个对象数据
定义一个数据类
@Parcelize
data class EmailModel(val id:Int,var name:String,var password:String):Parcelable
自定义定义一个通用的NavType
inline fun <reified T : Parcelable> createParcelableNavType(isNullableAllowed: Boolean = false): NavType<T> {return object : NavType<T>(isNullableAllowed) {override val name: Stringget() = "SupportParcelable"override fun get(bundle: Bundle, key: String): T? { //从Bundle中检索 Parcelable类型return bundle.getParcelable(key)}override fun parseValue(value: String): T { //定义传递给 String 的 Parsing 方法return Gson().fromJson(value, T::class.java)}override fun put(bundle: Bundle, key: String, value: T) { //作为 Parcelable 类型添加到 Bundlebundle.putParcelable(key, value)}}
}navArgument("jsonParcelable"){type = createParcelableNavType<EmailModel>()
}
设置一个接受参数的占位符
object Detail:Screen(route = "$DETAIL?key={jsonParcelable}")
传递参数
fun passIdAndName(id:Int= 0,name:String="tanZuAi",password:String="tanZuAi123"):String{val jsonParcelable = Gson().toJson(EmailModel(id,name, password))return "$DETAIL?key=${Uri.encode(jsonParcelable)}"
}
接收参数
val emailModel = navBackStackEntry.arguments?.getParcelable<EmailModel>("jsonParcelable")emailModel?.apply {DetailScreen(id,name,password,navController = navController)
}
注:至此,通过 Parcelable 传递对象数据就讲完了
总结
- 普通方式传值:$DETAIL?id={id},name={name},password={password}
- ViewModel传值:继承 ViewModel() 类,在类中定义状态变量,通过监听变量值变化,获取变量值
- Parcelable传值:通过 Gson().toJson() 转换对象,传递值
相关文章:
Compose | UI组件(十四) | Navigation-Data - 页面导航传递数据
文章目录 前言传参流程实例说明普通方式传值定义接受参数格式定义接受参数类型获取参数传入参数传参和接受参数效果图 结合 ViewModel 传递参数定义ViewModel在 navigation 定义 ViewModel 实例,并且传入 LoginScreen传入输入框中的值,并且跳转传值获取值…...
部署一个在线OCR工具
效果 安装 1.拉取镜像 # 从 dockerhub pull docker pull mmmz/trwebocr:latest 2.运行容器 # 运行镜像 docker run -itd --rm -p 10058:8089 --name trwebocr mmmz/trwebocr:latest 使用 打开浏览器输入 http://192.168.168.110:10058/ 愉快滴使用吧...
【北邮鲁鹏老师计算机视觉课程笔记】01 introduction
1 生活中的计算机视觉 生活中的各种计算机视觉识别系统已经广泛地应用起来了。 2 计算机视觉与其他学科的关系 认知科学和神经科学是研究人类视觉系统的,如果能把人类视觉系统学习得更好,可以迁移到计算机视觉。是计算机视觉的理论基础。 算法、系统、框…...
maven依赖报错处理(或者maven怎么刷新都下载不了依赖)
maven依赖报错,或者不报错,但是怎么刷新maven都没反应,可以试一下以下操作 当下载jar的时候,如果断网,或者连接超时的时候,会自动在文件夹中创建一个名为*lastupdate的文件,当有了这个文件之后…...
[VulnHub靶机渗透] dpwwn: 1
🍬 博主介绍👨🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏…...
Android14音频进阶:MediaPlayerService如何启动AudioTrack 下篇(五十六)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…...
Python基础篇_修饰符(Decorators)【下】
上一篇:Python基础篇_修饰符(Decorators)【中】property、<attribute_name>.setter、<attribute_name>.deleter、functools.lru_cache(maxsizeNone) Python基础篇_修饰符(Decorators)【下】 Python基础篇_…...
C#,十进制展开数(Decimal Expansion Number)的算法与源代码
1 十进制展开数 十进制展开数(Decimal Expansion Number)的计算公式: DEN n^3 - n - 1 The decimal expansion of a number is its representation in base -10 (i.e., in the decimal system). In this system, each "decimal place…...
Vue3快速上手(一)使用vite创建项目
一、准备 在此之前,你的电脑,需要安装node.js,我这边v18.19.0 wangdymb 2024code % node -v v18.19.0二、创建 执行npm create vuelatest命令即可使用vite创建vue3项目 有的同学可能卡主不动,可能是npm的registry设置的问题 先看下&#x…...
使用navicat导出mysql离线数据后,再导入doris的方案
一、背景 doris本身是支持直接从mysql中同步数据的,但有时候,客户不允许我们使用doris直连mysql,此时就需要客户配合将mysql中的数据手工导出成离线文件,我们再导入到doris中 二、环境 doris 1.2 三、方案 doris支持多种导入…...
re:从0开始的CSS学习之路 1. CSS语法规则
0. 写在前面 现在大模型卷的飞起,感觉做页面的活可能以后就不需要人来做了,不知道现在还有没有学前端的必要。。。 1. HTML和CSS结合的三种方式 在HTML中,我们强调HTML并不关心显示样式,样式是CSS的工作,现在就轮到C…...
npm install express -g报错或一直卡着,亲测可解决
问题描述: 最近学习vue3前端框架,安装Node.js之后,在测试是否可行时,cmd窗口执行了:npm install express -g,发现如下图所示一直卡着不动,最后还报错了,网上找了好久,各…...
机器学习11-前馈神经网络识别手写数字1.0
在这个示例中,使用的神经网络是一个简单的全连接前馈神经网络,也称为多层感知器(Multilayer Perceptron,MLP)。这个神经网络由几个关键组件构成: 1. 输入层 输入层接收输入数据,这里是一个 28x…...
vscode wsl远程连接 权限问题
问题描述:执行命令时遇到Operation not permitted 和 Permission denied问题,是有关ip地址和创建文件的权限问题,参考网络上更改wsl.conf文件等方法均无法解决,只能加sudo来解决...
VED-eBPF:一款基于eBPF的内核利用和Rootkit检测工具
关于VED-eBPF VED-eBPF是一款功能强大的内核漏洞利用和Rootkit检测工具,该工具基于eBPF技术实现其功能,可以实现Linux操作系统运行时内核安全监控和漏洞利用检测。 eBPF是一个内核内虚拟机,它允许我们直接在内核中执行代码,而无…...
配置ARM交叉编译工具的通用步骤
ARM交叉编译工具是用于编译在ARM架构上运行的代码的工具。这些工具允许开发者在一种架构(通常是x86或x64)上编写和编译代码,然后将其移植到ARM架构上运行。 ARM交叉编译工具链通常包括编译器、链接器、调试器和其他必要的工具,用…...
相机图像质量研究(5)常见问题总结:光学结构对成像的影响--景深
系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…...
使用django构建一个多级评论功能
,评论系统是交流和反馈的重要工具,尤其是多级评论系统,它允许用户回复特定评论,形成丰富的对话结构。这个文章是使用Django框架从零开始构建一个多级评论系统。Django是一个高级Python Web框架,它鼓励快速开发和干净、…...
测试管理_利用python连接禅道数据库并自动统计bug数据到钉钉群
测试管理_利用python连接禅道数据库并统计bug数据到钉钉 这篇不多赘述,直接上代码文件。 另文章基础参考博文:参考博文 加以我自己的需求优化而成。 统计的前提 以下代码统计的前提是禅道的提bug流程应规范化 bug未解决不删除bug未关闭不删除 db_…...
Python 小白的 Leetcode Daily Challenge 刷题计划 - 20240209(除夕)
368. Largest Divisible Subset 难度:Medium 动态规划 方案还原 Yesterdays Daily Challenge can be reduced to the problem of shortest path in an unweighted graph while todays daily challenge can be reduced to the problem of longest path in an unwe…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
