如何避免 onClick 回调被多次调用 Jetpack Compose

Mau*_*ssi 5 android android-jetpack-compose jetpack-compose-navigation

在测试我的应用程序时,我意识到如果用户FloatingActionButton快速按下几次,onClick 回调可能会被多次触发。就我而言,这导致返回堆栈被多次弹出,因为onPopBackStack回调会冒泡到NavHost它可以访问navController并调用该popBackStack方法的位置。

fun AddEditTodoScreen(onPopBackStack: () -> Unit, viewModel: AddEditTodoViewModel = viewModel()) {

    var isNavigating by remember{
        mutableStateOf(false)
    }

    LaunchedEffect(key1 = true){
        viewModel.uiEvent.collect{event : UiEvent ->
            when(event){
                is UiEvent.PopBackStack -> onPopBackStack
                else -> Unit
            }
        }
    }

    Scaffold(floatingActionButton = {
        FloatingActionButton(onClick = {
            if(!isNavigating){
                isNavigating = !isNavigating
                onPopBackStack()
            }
        }) {
            Icon(imageVector = Icons.Default.Check, contentDescription = "Check")
        }
Run Code Online (Sandbox Code Playgroud)

目前,我只是在第一次单击isNavigating时将 a 设置为 true FloatingActionButton,如果再次单击,它会检查该isNavigating标志是否设置为 true,如果是,则不执行任何操作。如果有的话,有什么更好的方法来解决这个问题?

ian*_*ake 17

导航已经告诉您是否正在导航到新目的地:当您调用 时,Lifecycle的会同步更改,从而使您从该状态下移。NavBackStackEntrynavigateRESUMED

因此,如果您想避免在开始导航到另一个屏幕后处理点击,您需要检查 的LocalLifecycleOwner状态:

// This corresponds with the NavBackStackEntry
// associated with this screen
val lifecycleOwner = LocalLifecycleOwner.current

FloatingActionButton(onClick = {
    // Get the current state of the Lifecycle
    val currentState = lifecycleOwner.lifecycle.currentState

    // And ignore click events when you've started navigating
    // to another screen
    if (currentState.isAtLeast(Lifecycle.State.RESUMED)) {
        onPopBackStack()
    }
}
Run Code Online (Sandbox Code Playgroud)