附带效应是指发生在可组合函数作用域之外的应用状态的变化。由于可组合项的生命周期和属性(例如不可预测的重组、以不同顺序执行可组合项的重组或可以舍弃的重组),可组合项在理想情况下应该是无附带效应的。
不过,有时附带效应是必要的,例如,触发一次性事件(例如显示信息提示控件),或在满足特定状态条件时进入另一个屏幕。这些操作应从能感知可组合项生命周期的受控环境中调用。在本页中,您将了解 Jetpack Compose 提供的不同附带效应 API。
状态和效应用例
如 Compose 编程思想文档中所述,可组合项应该没有附带效应。如果您需要更改应用的状态(如管理状态文档中所述),您应该使用 Effect API,以便以可预测的方式执行这些附带效应。
。由于效应会在 Compose 中带来各种可能性,所以很容易过度使用。确保您在其中完成的工作与界面相关,并且不会破坏单向数据流,如管理状态文档中所述。
LaunchedEffect:在某个可组合项的作用域内运行挂起函数
如需在可组合项的生命周期内执行工作并能够调用挂起函数,请使用 LaunchedEffect 可组合项。当 LaunchedEffect 进入组合时,它会启动一个协程,并将代码块作为参数传递。如果 LaunchedEffect 退出组合,协程将取消。如果使用不同的键重组 LaunchedEffect(请参阅下方的重启效应部分),系统将取消现有协程,并在新的协程中启动新的挂起函数。
例如,以下动画会以可配置的延迟时间脉冲式变化 Alpha 值:
// Allow the pulse rate to be configured, so it can be sped up if the user is running // out of time var pulseRateMs by remember { mutableLongStateOf(3000L) } val alpha = remember { Animatable(1f) } LaunchedEffect(pulseRateMs) { // Restart the effect when the pulse rate changes while (isActive) { delay(pulseRateMs) // Pulse the alpha every pulseRateMs to alert the user alpha.animateTo(0f) alpha.animateTo(1f) } }
在上面的代码中,动画使用挂起函数 delay 等待设定的时间。然后,它使用 animateTo 将 Alpha 依次动画化为零,然后再动画化回来。
此操作将在可组合项的整个生命周期内重复执行。
rememberCoroutineScope:获取组合感知作用域,以便在可组合项外启动协程
由于 LaunchedEffect 是可组合函数,因此只能在其他可组合函数中使用。为了在可组合项外启动协程,但存在作用域限制,以便协程在退出组合后自动取消,请使用 rememberCoroutineScope。
此外,如果您需要手动控制一个或多个协程的生命周期,请使用 rememberCoroutineScope,例如在用户事件发生时取消动画。
rememberCoroutineScope 是一个可组合函数,会返回一个 CoroutineScope,该 CoroutineScope 绑定到调用它的组合点。调用退出组合后,作用域将取消。
根据上面的示例,当用户点按 Button 时,您可以使用以下代码显示 Snackbar:
@Composable fun MoviesScreen(snackbarHostState: SnackbarHostState) { // Creates a CoroutineScope bound to the MoviesScreen's lifecycle val scope = rememberCoroutineScope() Scaffold( snackbarHost = { SnackbarHost(hostState = snackbarHostState) } ) { contentPadding -> Column(Modifier.padding(contentPadding)) { Button( onClick = { // Create a new coroutine in the event handler to show a snackbar scope.launch { snackbarHostState.showSnackbar("Something happened!") } } ) { Text("Press me") } } } }
rememberUpdatedState:在效应中引用某个值,该效应在值改变时不应重启
当其中一个键参数发生变化时,