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…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...