'How to prevent onDismiss Callback to be call, in custom AlertDialog with Jetpack Compose
I was developing an app which I use Jetpack compose to define the UI.
I was implementing some localdatabase such as Room, and I try to implement the remove operation of my items. In order to confirm this operation by the user, I try to design a custom AlertDialog, with 2 buttons, one to confirm and another to dismiss the operation.
My problems comes, due to my dialog execute the call in the confirm button, and dismiss instantly, less than a second, show I try to don't pass the dismis callback, but doesn't work either.
Here is my code:
//At the begining is invisible and show when the user try to remove some pokemon.
@Composable
fun SimpleAlertDialog(
show: Boolean,
onConfirm: Unit,
onDismiss: KFunction0<Unit>
) {
if(show){
AlertDialog(
onDismissRequest = { onDismiss},
confirmButton = {
TextButton(onClick = {onConfirm})
{ Text(text = "OK") }
},
dismissButton = {
TextButton(onClick = {onDismiss})
{ Text(text = "Cancel") }
},
title = { Text(text = "Remove") },
text = { Text(text = "Would you like to remove the selected pokemon?") },
properties = DialogProperties(
dismissOnBackPress = true,
dismissOnClickOutside = false
)
)
}
}
@OptIn(ExperimentalFoundationApi::class)
@SuppressLint("LogNotTimber")
@Composable
fun PokedexRoomEntry(
entry: RoomResponse,
navController: NavController,
modifier: Modifier = Modifier,
viewModel: MyPokemonViewModel
) {
val defaultDominantColor = MaterialTheme.colors.surface
var dominantColor by remember {
mutableStateOf(defaultDominantColor)
}
val showDialogState: Boolean by viewModel.showDialog.collectAsState()
if(showDialogState){
SimpleAlertDialog(
show = showDialogState,
onConfirm = viewModel.onDialogConfirm(entry.pokemonName),
onDismiss = viewModel::onDialogDismiss)
}
Box(
...
Regarding the showDialogState, the callback of the dialog in the viewmodel are the following:
class MyPokemonViewModel @Inject constructor(
val localRepository: LocalRepository):
ViewModel() {
var pokemonBoughtList = mutableStateOf<List<RoomResponse>>(listOf())
var loadError = mutableStateOf("")
var isLoading = mutableStateOf(false)
// Initial value is false so the dialog is hidden
private val _showDialog = MutableStateFlow(false)
val showDialog: StateFlow<Boolean> = _showDialog.asStateFlow()
fun onOpenDialogClicked() {
_showDialog.value = true
}
fun onDialogConfirm(pokemonToRemove: String) {
viewModelScope.launch(Dispatchers.IO) {
_showDialog.value = false
removePokemon(pokemonToRemove)
}
}
fun onDialogDismiss() {
_showDialog.value = false
}
fun removePokemon(pokemonToRemove: String) = runBlocking(Dispatchers.IO){
isLoading.value = true
val resp = localRepository.removePokemon(pokemonToRemove = pokemonToRemove)
when(resp){
is WrapperResponse.Sucess -> {
//Nº files removed
if(resp.data != 0){
//Número de filas eliminadas
loadError.value = ""
isLoading.value = false
}else{
loadError.value = "No se ha podido eliminar el pokemon seleccionado"
isLoading.value = false
}
}
is WrapperResponse.Error -> {
loadError.value = resp.message.toString()
isLoading.value = false
}
}
}
As I said, the diolog is shown when I invoke the onLongPress listener, but almost instanly, the code inside onConfirm callback, and then onDismiss callbak are call, without let the user take any action in the dialog.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
