You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

快速返回导航未重置自定义动画的解决方法求助

解决方案:恢复Screen1中AnimatedVisibility的可见状态

问题核心是:从Screen1导航到Screen2时visibleBox1被设为false,但快速返回Screen1时该状态未自动重置,导致Box保持不可见。可通过监听导航栈变化或生命周期事件主动重置状态。

方法一:监听导航路由重置状态

在Screen1中添加导航路由监听,当路由回到Screen1时,将visibleBox1重置为true:

@Composable
fun Screen1(navController: NavController) {
    val lifecycleOwner = LocalLifecycleOwner.current
    LaunchedEffect(Unit) {
        Log.i("Screen1", "Created")
    }

    DisposableEffect(lifecycleOwner) {
        onDispose {
            Log.i("Screen1", "OnDispose")
        }
    }

    var visibleBox1 by remember { mutableStateOf(true) }
    
    // 监听当前导航路由,回到Screen1时重置Box可见性
    val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
    LaunchedEffect(currentRoute) {
        if (currentRoute == "Screen1") {
            visibleBox1 = true
        }
    }

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
        )
        AnimatedVisibility(visible = visibleBox1, exit = slideOutVertically()) {
            Box(
                modifier = Modifier
                    .height(100.dp)
                    .fillMaxWidth()
                    .background(color = Color.Red)
            )
        }

        Button(onClick = {
            visibleBox1 = false
            Log.i("Screen1_Button", "OnClick,navigate to Screen2")
            navController.navigate("Screen2")
        }) {
            Text("navigate to Screen2")
        }
    }
}

原理

navController.currentBackStackEntryAsState()实时监听导航栈变化,从Screen2返回Screen1时,currentRoute更新为"Screen1",触发LaunchedEffect将visibleBox1设为true,让AnimatedVisibility重新显示Box。

方法二:通过生命周期事件重置状态

利用Compose生命周期监听,当Screen1恢复到前台(进入RESUMED状态)时重置状态:

@Composable
fun Screen1(navController: NavController) {
    val lifecycleOwner = LocalLifecycleOwner.current
    val lifecycle = lifecycleOwner.lifecycle
    LaunchedEffect(Unit) {
        Log.i("Screen1", "Created")
    }

    DisposableEffect(lifecycleOwner) {
        onDispose {
            Log.i("Screen1", "OnDispose")
        }
    }

    var visibleBox1 by remember { mutableStateOf(true) }
    
    // 监听Screen1的生命周期,进入RESUMED状态时重置Box可见性
    LaunchedEffect(lifecycle) {
        lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
            visibleBox1 = true
        }
    }

    // 其余布局代码与原代码一致
}

原理

repeatOnLifecycle(Lifecycle.State.RESUMED)会在组件进入前台时执行代码,确保Screen1从后台(被Screen2覆盖)回到前台时,visibleBox1被重置为true,恢复Box的可见性。

关键说明

两种方法各有侧重:

  • 方法一直接绑定导航行为,仅在回到Screen1时触发重置;
  • 方法二更通用,覆盖所有导致Screen1从后台回到前台的场景。

内容的提问来源于stack exchange,提问作者Nicron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:13:17