如何在Jetpack Compose中监听NavHostController导航过渡完成并接收回调
Jetpack Compose 导航过渡完成后触发回调的实现方法
方案一:自定义导航过渡并绑定结束回调
在配置NavHost的页面过渡动画时,直接给过渡对象添加onEnd回调,精准捕捉动画结束时机:
NavHost(navController = navController, startDestination = "home") { composable("home") { // 首页内容 } composable( "detail", enterTransition = { slideInHorizontally(initialOffsetX = { it }) + fadeIn() .apply { // 过渡动画结束时触发回调 onEnd { transitionFinished() } } }, exitTransition = { slideOutHorizontally(targetOffsetX = { -it }) + fadeOut() } ) { // 详情页内容 } }
这种方式直接和页面的过渡动画绑定,回调时机完全匹配动画结束节点。
方案二:结合生命周期监听全局过渡完成
如果需要全局监听所有页面的导航过渡,可通过navController.currentBackStackEntryAsState监听目的地变化,再配合页面生命周期确定过渡完成:
val currentBackStackEntry by navController.currentBackStackEntryAsState() LaunchedEffect(currentBackStackEntry) { currentBackStackEntry?.let { entry -> // 等待页面进入RESUMED状态,确保过渡动画已完成 entry.lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) { transitionFinished(entry.destination.route) } } }
如果你的过渡动画时长较长,RESUMED可能提前触发,可额外添加delay匹配动画时长来保证精准性。
方案三:封装全局监听工具类
若需复用过渡监听逻辑,可封装工具函数和NavController绑定:
fun NavController.addOnTransitionFinishedListener(callback: (String?) -> Unit) { val currentEntry = currentBackStackEntryAsState() LaunchedEffect(currentEntry.value) { currentEntry.value?.let { entry -> entry.lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) { // 可选:添加延迟匹配动画时长 // delay(300) callback(entry.destination.route) } } } } // 使用示例 navController.addOnTransitionFinishedListener { route -> println("导航到[$route] 过渡完成") }
内容的提问来源于stack exchange,提问作者Vaio
相关产品推荐
相关产品推荐

