目录结构
一个简单 Demo 的文件分离结构:
- Home Screen:首页列表
- Edit Screen (detail):编辑页
- NavHost (router):路由定义
- Main Activity
添加依赖
dependencies {
implementation "androidx.navigation:navigation-compose:2.4.0-alpha08"
}
添加之后,不要忘了点击 Android Studio 右上角的 Sync Now。 否则像 rememberNavController 这样的函数,无法通过 Alt + Enter 自动添加引用。
注意:同时需要将 build.gradle 中的 compileSdk 和 targetSdk 由 30 修改为 31,否则会报错。 详见下面的编译错误记录。
这个版本号,应该是随时在更新的。如何查看最新的版本号?
navigation-compose 引起的编译报错
在 preview 预览编译时,报错:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckAarMetadataWorkAction
> One or more issues found when checking AAR metadata values:
The minCompileSdk (31) specified in a
dependency's AAR metadata (META-INF/com/android/build/gradle/aar-metadata.properties)
is greater than this module's compileSdkVersion (android-30).
Dependency: androidx.navigation:navigation-compose:2.4.0-alpha08.
从提示上看是,androidx.navigation:navigation-compose:2.4.0-alpha08 依赖 minCompileSdk 31, 而 build.gradle 中设置的 compileSdk 为 30.
解决方法就是将 compileSdk 和 targetSdk 都由 30 改为 31.
android {
compileSdk 31
defaultConfig {
applicationId "com.sunzhongwei.app"
minSdk 21
targetSdk 31
再次编译成功。
NavHost
定义路由:
enum class DemoScreen {
HomeScreen,
EditScreen
}
@Composable
fun DemoNavHost(
navController: NavHostController
) {
NavHost(
navController = navController,
startDestination = DemoScreen.HomeScreen.name
) {
composable(DemoScreen.HomeScreen.name) {
HomeScreen(navController = navController)
}
composable(DemoScreen.EditScreen.name) {
EditScreen(navController = navController)
}
}
}
- NavController: 记录 path 栈
- NavHost: 定义多 composable 界面间的路由关系
HomeScreen
定义首页界面 UI, 及操作
@Composable
fun HomeScreen(navController: NavController) {
Scaffold(
drawerContent = { /*...*/ },
topBar = { /*...*/ },
content = {
Items(items)
},
floatingActionButton = {
FloatingActionButton(onClick = {
navController.navigate(ShelfLifeScreen.EditScreen.name)
}) {
Icon(Icons.Filled.Add,"")
}
}
)
}
EditScreen
@Composable
fun EditScreen(navController: NavController) {
Text(text = "test")
}
MainActivity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeNavigation()
}
}
}
@Composable
fun ComposeNavigation() {
val navController = rememberNavController()
DemoNavHost(
navController = navController,
)
}
带有 NavController 的 composable 如何预览
由于 HomeScreen 添加了 NavController 参数,所以预览失效:
No value passed for parameter 'navController'
加上一个参数即可。
@Preview
@Composable
fun PreviewHome() {
val navController = rememberNavController()
HomeScreen(navController)
}
参考
- Navigating with Compose (Android 官方文档)
- 当 Jetpack Compose 遇到 Navigation (公众号文章) 代码组织更容易理解
- minSdkVersion, targetSdkVersion, compileSdkVersion 各自作用
微信关注我哦 👍
我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式