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…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
