androidkotlinandroid-jetpack-composeandroid-jetpack-compose-scaffold

How to pass events to Composables?


I have two composables like this:

@Composable
fun Composable1(viewModel: MyViewModel) {
    LaunchedEffect(Unit) {
        viewModel.eventsFlow.collect { event ->
            if(event is ShowSnackbar) {
                // Send this event to Composable2 to show snackbar
            }
        }
    }
    Composable2(...) // passing some data and lambdas
}

@Composable
fun Composable2(...) {
    val scaffoldState = rememberScaffoldState()

    // On receiving event, show a snackbar

    Scaffold(scaffoldState) {
        // Other stuff
    }
}

(If another ShowSnackbar event comes while one snackbar is visible, I want to ignore that new event)

How to send such an event from one composable to another?


Solution

  • I created a small example. I hope It is help you. In my case I generate a "event" by means of clicking a button

    class ComposeActivity5 : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContent {
                ComposeTutorialTheme {
                    Composable1()
                }
            }
        }
    }
    
    @Composable
    fun Composable1() {
        val scaffoldState = rememberScaffoldState()
        var showHide by remember { mutableStateOf(false) }
        var pressCount by remember { mutableStateOf(0) }
    
        Scaffold(
            scaffoldState = scaffoldState,
            content = { innerPadding ->
                Column(
                    horizontalAlignment = Alignment.CenterHorizontally,
                    modifier = Modifier
                        .padding(innerPadding)
                        .fillMaxSize()
                ) {
                    Button(onClick = {
                        pressCount++
                        showHide = true
    
                    }) {
                        Text(text = "Test")
                    }
                    Composable2(scaffoldState, showHide, pressCount) {
                        showHide = false
                    }
                }
            }
        )
    }
    
    @Composable
    fun Composable2(
        scaffoldState: ScaffoldState,
        showHide: Boolean,
        pressCount: Int,
        onDismiss: () -> Unit
    ) {
        val mostRecentOnDismiss by rememberUpdatedState(onDismiss)
        LaunchedEffect(scaffoldState, showHide) {
            if (showHide) {
                scaffoldState.snackbarHostState.showSnackbar(
                    message = "We are ignore press button to show Snackbar. Total number of clicks $pressCount",
                    actionLabel = "Close",
                    duration = SnackbarDuration.Short,
                )
                mostRecentOnDismiss()
            }
        }
    }