Home > Mobile >  How to get the rootView inside composable function?
How to get the rootView inside composable function?

Time:08-03

In my activity I have a composable function:

@Composable
private fun checkResponse() {
    when(val response = viewModel.response) {
        is Success -> //...
        is Failure -> showSnackBar() //Here is the problem.
    }
}

The showSnackBar() is this:

private fun showSnackBar(rootView: View) {
    Snackbar.make(rootView, "Error", Snackbar.LENGTH_LONG).show()
}

Which takes as an argument the rootView. How to call showSnackBar and pass the correct argument?

CodePudding user response:

You can get root View with LocalView.current but you don't need it if it's for showing SnackBar.

You can display SnackBar, if you are using Scaffold with

val scaffoldState: ScaffoldState = rememberScaffoldState()

And

androidx.compose.material.Scaffold(
    scaffoldState = scaffoldState,
    content = {
        Column(Modifier.padding(it)) {
            Button(onClick = {
                coroutineScope.launch {
                    scaffoldState.snackbarHostState.showSnackbar("Hello World")
                }
            }) {
                Text("Show Snackbar")
            }
        }
    }
)

You can use LaunchedEffect to cancel if you don't want to wait for duration to end as

LaunchedEffect(scaffoldState.snackbarHostState) {
    // Show snackbar using a coroutine, when the coroutine is cancelled the
    // snackbar will automatically dismiss. This coroutine will cancel whenever
    // if statement is false, and only start when statement is true
    // (due to the above if-check), or if `scaffoldState.snackbarHostState` changes.
    scaffoldState.snackbarHostState.showSnackbar("LaunchedEffect snackbar")
}

If you don't have a Scaffold you can use SnackBar composable as

Box(modifier = Modifier.fillMaxSize()) {
    var showSnackbar by remember {
        mutableStateOf(false)
    }

    LaunchedEffect(key1 = showSnackbar) {
        if (showSnackbar) {
            delay(2000)
            showSnackbar = false
        }
    }


    Column {

        Button(onClick = {
            showSnackbar = !showSnackbar
        }) {
            Text("Show Snackbar")
        }
    }

    if (showSnackbar) {
        androidx.compose.material.Snackbar(modifier = Modifier.align(Alignment.BottomStart),
            action = {
                Text(text = "Action",
                    color = Color(0xffCE93D8),
                    modifier = Modifier.clickable {
                        showSnackbar = false
                    }
                )
            }) {
            androidx.compose.material.Text("Message")
        }
    }
}

LaunchedEffect is to remove it from composition. You can use a slide animation if you want to.

  • Related