Skip to content

Instantly share code, notes, and snippets.

@Nunocky
Last active December 1, 2024 12:59
Show Gist options
  • Save Nunocky/c6a20afcbd868ef9e6283a8c13026e05 to your computer and use it in GitHub Desktop.
Save Nunocky/c6a20afcbd868ef9e6283a8c13026e05 to your computer and use it in GitHub Desktop.
How to use AlertDialog in Jetpack Compose
// implementation(libs.androidx.lifecycle.viewmodel.ktx)
// implementation(libs.androidx.lifecycle.runtime.compose.android)
// implementation(libs.androidx.lifecycle.viewmodel.compose)
private suspend fun someAsyncFunction(): String {
delay(3000L)
// return "Hello"
throw Exception("error")
}
sealed class UiStateX {
data object Idle : UiStateX()
data object Loading : UiStateX()
data class Success(val text: String) : UiStateX()
data class Error(val message: String) : UiStateX()
}
class MainViewModel : ViewModel() {
private val _uiState = MutableStateFlow<UiStateX>(UiStateX.Idle)
val uiState = _uiState.asStateFlow()
private var _shouldShowDialog = MutableStateFlow(false)
val shouldShowDialog = _shouldShowDialog.asStateFlow()
fun processASyncFunction() {
viewModelScope.launch(Dispatchers.IO) {
_uiState.value = UiStateX.Loading
runCatching {
someAsyncFunction()
}.onSuccess { text ->
_uiState.value = UiStateX.Success(text)
}.onFailure {
_shouldShowDialog.value = true
_uiState.value = UiStateX.Error(it.message ?: "unknown error")
}
}
}
fun onDialogDismissed() {
_shouldShowDialog.value = false
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(modifier: Modifier = Modifier, viewModel: MainViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
val shouldShowDialog by viewModel.shouldShowDialog.collectAsStateWithLifecycle()
Column(modifier = modifier) {
when (val state = uiState) {
UiStateX.Idle -> {
Button(onClick = { viewModel.processASyncFunction() }) {
Text("Click")
}
}
UiStateX.Loading -> {
Text("loading...")
}
is UiStateX.Success -> {
Column {
Text(state.text)
Button(onClick = { viewModel.processASyncFunction() }) {
Text("Click")
}
}
}
is UiStateX.Error -> {
Text(state.message)
Button(onClick = { viewModel.processASyncFunction() }) {
Text("Click")
}
}
}
}
if (shouldShowDialog) {
BasicAlertDialog(onDismissRequest = {
viewModel.onDialogDismissed()
}) {
Surface(
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight(),
shape = MaterialTheme.shapes.large,
tonalElevation = AlertDialogDefaults.TonalElevation
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "something went wrong")
Spacer(modifier = Modifier.height(24.dp))
TextButton(
onClick = {
viewModel.onDialogDismissed()
},
modifier = Modifier.align(Alignment.End)
) {
Text("Confirm")
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment