Android开发 Jetpack Compose navigation导航
前言
此篇博客讲解Jetpack Compose的导航功能。官方文档:https://developer.android.google.cn/jetpack/compose/navigation?hl=zh-cn
还在使用xml开发应用的时候,之前的Jetpack系列的开发工具中,Navigation的框架的使用结构通常是这样的:
Actvity
->AFragment
->BFragment
由一个根Activity管理多个Fragment通过导航管理器来控制跳转,返回。(当然有些情况下Activity也可以通过导航互相跳转)
在新的Jetpack Compose Navigation下,其实已经没有了Fragment的概念了。或者说Jetpack Compose其实已经不需要Fragment的概念了,如果你已经了解过Compose应该有所察觉。Composable方法其实可以作为Fragment来使用。所以Jetpack Compose Navigation主要就是从一个Composable方法导航到另一个Composable方法。
参考
依赖
如果你不知道最新版本,可以通过官网文档查看
//jetpack compose导航
implementation("androidx.navigation:navigation-compose:2.5.3")
一个简单的跳转导航
效果图

代码
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
class DemoActivity : AppCompatActivity() {
private lateinit var mNavController: NavHostController
companion object {
fun jump(context: Context) {
context.startActivity(Intent(context, DemoActivity::class.java))
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DemoNavigation()
}
}
@Composable
fun DemoNavigation() {
//创建导航控制器
mNavController = rememberNavController()
//创建NavHost导航组建者,传入了mNavController 导航控制器 与 首个显示的页面 startDestination = APage
NavHost(navController = mNavController, startDestination = "APage") {
//这里添加了页面A,APage为路由地址
composable( route = "APage") { APage() }
//这里添加了页面B
composable( route ="BPage") { BPage() }
}
}
/**
* 页面A
*/
@Composable
fun APage() {
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button(onClick = { mNavController.navigate("BPage") }) {
Text(text = "页面A: 点击跳转页面B", fontSize = 40.sp)
}
}
}
/**
* 页面B
*/
@Composable
fun BPage() {
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button(onClick = { mNavController.navigateUp() }) {
Text(text = "页面B: 点击返回页面A", fontSize = 40.sp)
}
}
}
}
带参跳转
效果图

代码
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
class DemoActivity : AppCompatActivity() {
private lateinit var mNavController: NavHostController
companion object {
fun jump(context: Context) {
context.startActivity(Intent(context, DemoActivity::class.java))
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DemoNavigation()
}
}
@Composable
fun DemoNavigation() {
mNavController = rememberNavController()
NavHost(navController = mNavController, startDestination = "APage") {
composable(route = "APage") { APage() }
composable(
//在路径后面直接填入{key}传参,请注意在?后面的参数为非必填参数,这里的sex在传入的时候可填可不填
route = "BPage/{id}/{name}?sex={sex}", arguments = listOf(navArgument("id") {
type = NavType.IntType //设置传值的类型
defaultValue = -1 //设置默认值
}, navArgument("name"){
type = NavType.StringType
defaultValue = "null"
}, navArgument("sex"){
type = NavType.BoolType
defaultValue = true
})
) { it -> BPage(it) }
}
}
/**
* 页面A
*/
@Composable
fun APage() {
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
//如果这里不填sex=false,sex则会默认为true
Button(onClick = { mNavController.navigate("BPage/123/小明") }) {
Text(text = "页面A: 点击跳转页面B", fontSize = 40.sp)
}
}
}
/**
* 页面B
*/
@Composable
fun BPage(it: NavBackStackEntry) {
val id = it.arguments?.getInt("id")
val name = it.arguments?.getString("name")
val sex = it.arguments?.getBoolean("sex")
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "传过来的Id = ${id} 名称 = ${name} 性别 = ${sex}", fontSize = 40.sp)
Button(onClick = { mNavController.navigateUp() }) {
Text(text = "页面B: 点击返回页面A", fontSize = 40.sp)
}
}
}
}
end