名词解释
什么是正向反向参数传递呢
正向:相当于一个Activity 启动另一个Activity 并向其传递参数; 反向:相当于一个Activity 退出的时候向启动它的Activity 回传参数;
思路
本文主要讲反向参数传递,正向参数传递参考:正向参数传递
起先关于这个问题是没什么思路的,网上(包括google官网)也没有相关说明,以至于公司新开的项目,虽然使用compose 来写的,但是反向参数传递却是自定义的一个总线框架来做的。
使用总线框架做明显是不合适的。
基于这样一个原因,项目完成后我决定研究一下这个问题。
我们都知道compose的页面打开关闭是使用NavHostController 来进行的,那么有理由相信,如果有反向数据传递的方法必然也与NavHostController 来处理。
后面的做法也简单,将所有的NavHostController 中方法过一遍基本就能过滤出可能的几个。
通过过滤有几个方法被选中:findDestination 、getBackStackEntry 、previousBackStackEntry 、controller.currentBackStackEntryAsState() 。
最终有效的方法刚好就是:getBackStackEntry 、previousBackStackEntry ,通过这两个方法可以获取NavBackStackEntity ,而NavBackStackEntity 中有arguments:Bundle 参数,通过arguments参数就可以进行数据传递。
在上级页面使用controller.currentBackStackEntryAsState() 可以获取到Bundle 从而拿到返回的参数。
代码
方法封装
我将回传参数的代码进行封装如下
方法1: goBackRouteWithParams 获取指定某个route页面,并回传参数
方法2: goBackWithParams 直接返回上级页面,并回传参数
fun NavHostController.goBackRouteWithParams(
route: String,
autoPop: Boolean = true,
callback: (Bundle.() -> Unit)? = null,
) {
getBackStackEntry(route).arguments?.let {
callback?.invoke(it)
}
if (autoPop) {
popBackStack()
}
}
fun NavHostController.goBackWithParams(
autoPop: Boolean = true,
callback: (Bundle.() -> Unit)? = null,
) {
previousBackStackEntry?.arguments?.let {
callback?.invoke(it)
}
if (autoPop) {
popBackStack()
}
}
业务代码
@Composable
fun NavigateParams1View(controller: NavHostController) {
val bundle = controller.currentBackStackEntryAsState().value
Column(Modifier
.fillMaxSize()
.background(Color.Red),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "展示下一级页面返回来的数据", style = TextStyle(fontSize = 20.sp))
Box(Modifier
.padding(horizontal = 14.dp, vertical = 20.dp)
.size(120.dp)
.background(color = Color.Gray, RoundedCornerShape(10.dp)),
contentAlignment = Alignment.Center
) {
Text(text = bundle?.arguments?.getString("data") ?: "未返回数据")
}
Button(onClick = {
controller.navigate(navigate_param_transfer2)
}, modifier = Modifier.padding(top = 20.dp)) {
Text(text = "点击跳转到下一级页面")
}
}
}
@Composable
fun NavigateParams2View(controller: NavHostController) {
Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "展示下一级页面返回来的数据")
Button(onClick = {
controller.goBackRouteWithParams(navigate_param_transfer1) {
putString("data",
"Hello world to you")
}
},modifier = Modifier.padding(top = 20.dp)) {
Text(text = "点击跳转到下一级页面")
}
Button(onClick = {
controller.goBackWithParams {
putString("data", "Hello world to you")
}
},modifier = Modifier.padding(top = 20.dp)) {
Text(text = "点击跳转到下一级页面")
}
}
}
实现效果
|