c语言sscanf函数的用法是什么
308
2022-08-23
Jetpack Compose 的 Navigation学习
文章目录
1. 概述2. Navgation api
2.1 使用 `NavHost`2.2 composable()
2.2.1 注释1:id2.2.2 注释2: arguments2.2.3 注释3:lambda表达式
2.3 页面跳转2.4 DeepLink2.5 嵌套结构
官网
1. 概述
Navigation 是 Jetpack 用于 Android 导航的组件,作用是处理页面跳转,以及页面跳转过程中的交互。
使用 Navigation,你就需要为每个页面设定一条唯一路径,它是一个 String 常量,形式是 DeepLink 的样子,从一个页面跳转到另一个页面,它通过输入目的地的路径进行转跳。
Navigation 也支持上 Compose,我们可以在 Compose 中使用它来进行跳转。
因为官网和所看到的demo都是把它作为跳转能力使用,所以不清楚 Compose 是否还有别的跳转方式…
2. Navgation api
2.1 使用 NavHost
NavHost 可以用来描述导航图,就是可以在上面指定那些可以跳转的页面(像是注册路由一样),如果你需要从一个页面跳到另一个页面,你需要改变路线, NavHost 会触发重组,然后跳转到目的地。
NavHost 的重组是由 NavController 触发的,它代表了 NavHost 的状态, 是 Navigation 在 Compose 的中心 api, 它有两个作用:
跟踪界面上可组合项的回退栈跟踪界面上每个可组合项的状态
我们通过下面方式创建它:
val navController = rememberNavController()
要使用 NavHost, 必须要绑定一个 NavController,并且通过 startDestination 设置一个默认起始页面:
NavHost(navController = navController, startDestination = "profile") { composable("profile") { Profile(/*...*/) } composable("friendslist") { FriendsList(/*...*/) } /*...*/}
2.2 composable()
上面在 NavHost 中填入的 composable 是什么呢?
composable(..) { ... } 是 Navigation 提供的 DSL,它可以让我们添加可导航的页面,一个 composable() 可以视为注册一个可导航页面,就像下面这样:
// 为 Profile 赋予导航能力,相当于注册到路由表上composable( "profile?userId={userId}", // 1 arguments = listOf(navArgument("userId") { defaultValue = "me" }) // 2) { backStackEntry -> // 3 Profile(navController, backStackEntry.arguments?.getString("userId"))}
它一般有三个参数,下面逐一解释。
2.2.1 注释1:id
表示页面的路径,是页面的导航标识,是 String 类型。
可以通过 {...}设置占位符,例如例子里面的 userId。
还可以扩展其能力,做为 deeplink,例如跳转到 web 页,具体将在下面讲解。
2.2.2 注释2: arguments
导航目的地的可组合项所需参数,是可选参数, 需要使用 NavArgument 组成的列表携带。
默认情况下,所有参数都会作为字符串被解析, 我们可以通过 type设置。
NavHost(startDestination = "profile/{userId}/{age}") { ... composable( "profile/{userId}/{age}", arguments = listOf( navArgument("userId") { type = NavType.StringType }, // 这里可以不用写,因为默认就是字符串 navArgument("age") { type = NavType.IntType } // 需要显式设置为 Int 类型 ) ) {...}}
我们还可以为 navArgument 设置别的可选参数,例如 defaultValue 或 nullability = true(默认值可空):
navArgument("userId") { default = "123456" }
2.2.3 注释3:lambda表达式
它是一个用于构造一个可组合项,表示页面内容。看起来是一个 (NavBackStackEntry) -> @Compsable() 类型。
NavBackStackEntry 表示回退栈信息, 它的 argument 携带了打开页面所需要的参数,我们可以使用它来提取参数,然后构造可组合项:
composable("profile/{userId}") { backStackEntry -> Profile(navController, backStackEntry.arguments?.getString("userId"))}
2.3 页面跳转
通过调用 navController.navgate(..) 进行导航, 参数是目的地的标识,如下所示:
@Composablefun Profile(navController: NavController) { /*...*/ Button(onClick = { navController.navigate("friendslist") }) { Text(text = "Navigate next") } /*...*/}
需要注意的是,我们需要在回调中才能使用它,避免在可组合项中直接使用,避免重组时调用了它。
如果我们需要携带参数,可以直接填入:
navController.navigate("profile/user1234")navController.navigate("profile/${getUid()}")
默认情况下, navigate 会将新目的地添加到回退栈中,我们可以通过添加别的参数来改变这个行为:
// 在进入"friendsList"之前,回退栈会弹出所有的可组合项,直到 "home"navController.navigate("friendslist") { popUpTo("home")}// 在进入"friendsList"之前,回退栈会弹出所有的可组合项,直到 "home",并且包括它navController.navigate("friendslist") { popUpTo("home") { inclusive = true }}// 对应 Android 的 SingleTop,如果回退栈顶部已经是 "search",就不会重新创建navController.navigate("search") { launchSingleTop = true}
更多能力请参考: popUpTo 指南
2.4 DeepLink
Navigation Compose 支持隐式深层链接,此类链接也可定义为 composable() 函数的一部分。使用 navDeepLink() 以列表的形式添加深层链接。
例如下面代码中定义的导航项,它将页面参数拼接到 deepLink:
val uri = " "profile?id={id}", deepLinks = listOf(navDeepLink { uriPattern = "$uri/{id}" })) { backStackEntry -> Profile(navController, backStackEntry.arguments?.getString("id"))}
借助这些深层链接,可以将特定的网址、操作和/或 MIME 类型与可组合项关联起来。
我们可以在 manifest.xml 文件添加相应的
当其他应用触发该深层链接时,Navigation 会自动深层链接到相应的可组合项。
这些深层链接还可用于构建包含可组合项中的相关深层链接的 PendingIntent:
val id = "exampleId"val context = LocalContext.currentval deepLinkIntent = Intent( Intent.ACTION_VIEW, " context, MyActivity::class.java)val deepLinkPendingIntent: PendingIntent? = TaskStackBuilder.create(context).run { addNextIntentWithParentStack(deepLinkIntent) getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)}
2.5 嵌套结构
一个 NavHost 内注册的可组合项看起来是平铺的,没有深层结构。 我们可以通过 navigation 函数为其增加嵌套内容。
例如下面定义一个导航结构, “login” 可组合项又可以导航到 “username”、“password”、“registration” 这三个可组合项,而不让别的与 login 同级的可组合项进入,我们可以这样写:
NavHost(navController, startDestination = "home") { ... // 通过 route 来为'login' 定义一个更深层次的导航图 // 因此'username'封装了图的内部路由逻辑 navigation(route = "login", startDestination = "username") { composable("username") { ... } composable("password") { ... } composable("registration") { ... } } ...}
官方建议,如果在导航图比较大时,将其作为扩展函数拆分一下,以调高代码可读性:
fun NavGraphBuilder.loginGraph(navController: NavController) { navigation(startDestination = "username", route = "login") { composable("username") { ... } composable("password") { ... } composable("registration") { ... } }}// 使用:NavHost(navController, startDestination = "home") { ... loginGraph(navController) ...}
官网
使用 Compose 进行导航
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~