LazyColumn列表项中IconButton点击导航失效问题排查
问题描述
点击TaskItem中的编辑IconButton,预期跳转至UpdateScreen页面,但功能失效,Logcat及Run面板均无报错信息。截图显示任务列表项包含编辑图标按钮。
相关代码
Screen.kt
package com.example.planner sealed class Screen(val route: String) { object TasksList: Screen(route = "tasks_list") object AddScreen: Screen(route = "add_screen") object UpdateScreen: Screen(route = "update_screen") }
NavGraph.kt
package com.example.planner import androidx.compose.runtime.Composable import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @Composable fun Navigation(navController: NavHostController) { NavHost(navController = navController, startDestination = Screen.TasksList.route) { composable( route = Screen.TasksList.route ) { TasksList(navController = navController) } composable( route = Screen.AddScreen.route ) { AddScreen(navController = navController) } composable( route = Screen.UpdateScreen.route ) { UpdateScreen(navController = navController) } } }
TaskItem.kt(部分代码)
IconButton(onClick = { navController.navigate(route = Screen.UpdateScreen.route) }, modifier = Modifier.size(36.dp)) { Icon( imageVector = Icons.Filled.Edit, contentDescription = "Edit", modifier = Modifier.padding(horizontal = 2.dp), tint = MaterialTheme.colorScheme.onBackground ) }
MainActivity.kt
class MainActivity : ComponentActivity() { private lateinit var navController: NavHostController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { PlannerTheme { // A surface container using the "background" color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { navController = rememberNavController() Navigation(navController = navController) MyApp(Modifier.fillMaxSize(), navController) } } } } } @Composable fun MyApp(modifier: Modifier = Modifier, navController: NavController) { Surface(modifier, color = MaterialTheme.colorScheme.background) { TasksList(navController = navController) } } @Preview(name = "LightMode", showBackground = true) @Preview(name = "DarkMode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(name = "FullPreview", showBackground = true, showSystemUi = true) @Composable fun DefaultPreview() { PlannerTheme { Surface(modifier = Modifier, color = MaterialTheme.colorScheme.background) { TasksList(navController = rememberNavController()) } } }
问题原因
MainActivity的setContent中同时调用了Navigation和MyApp,MyApp直接渲染了全屏的TasksList组件,完全覆盖了Navigation中的NavHost容器。当前显示的TasksList并非导航框架托管的实例,因此点击按钮时的navController.navigate无法触发页面跳转。
解决方案
删除MainActivity中Navigation之后的MyApp调用,仅保留Navigation即可:
class MainActivity : ComponentActivity() { private lateinit var navController: NavHostController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { PlannerTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { navController = rememberNavController() Navigation(navController = navController) // 移除MyApp调用 } } } } } // MyApp组件可保留,如需使用可整合到Navigation的composable中 @Composable fun MyApp(modifier: Modifier = Modifier, navController: NavController) { Surface(modifier, color = MaterialTheme.colorScheme.background) { TasksList(navController = navController) } } // 预览代码保持不变 @Preview(name = "LightMode", showBackground = true) @Preview(name = "DarkMode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(name = "FullPreview", showBackground = true, showSystemUi = true) @Composable fun DefaultPreview() { PlannerTheme { Surface(modifier = Modifier, color = MaterialTheme.colorScheme.background) { TasksList(navController = rememberNavController()) } } }
说明
Navigation中的NavHost已经负责管理所有页面的导航逻辑,包括启动页TasksList。直接调用MyApp会在导航容器上层叠加独立的TasksList实例,脱离导航框架的管理,导致导航操作失效。移除MyApp调用后,界面由NavHost托管,点击按钮的导航逻辑即可正常运行。
内容的提问来源于stack exchange,提问作者Juncu
相关产品推荐
相关产品推荐

