setOnKeyListener for AlertDialog in jetpack compose

Viewed 325

We can have a listener for dialog in Android:

dialog.setOnKeyListener(new Dialog.OnKeyListener() {

  @Override
  public boolean onKey(DialogInterface arg0, int keyCode,KeyEvent event)
  {
     if (keyCode == KeyEvent.KEYCODE_BACK) {
           /* The user pressed back button - do whatever here.
           Normally you dismiss the dialog like dialog.dismiss(); */

         }
        return true;
        }
    });

How we can do that for AlertDialog in Jetpack Compose?

@Composable
private fun DisplayAlertDialog() {
    val openDialog = remember { mutableStateOf(true) }
    if (openDialog.value) {
        AlertDialog(
            onDismissRequest = {  },
            title = {
                Text(
                    text = stringResource(id = R.string.settings),
                    fontSize = 18.sp
                )
            },
            confirmButton = {
                TextButton(
                    onClick = {
                        openDialog.value = false
                    }
                ) {
                    Text(stringResource(id = R.string.yes))
                }
            },
            dismissButton = {
                TextButton(
                    onClick = {
                        openDialog.value = false
                    }
                ) {
                    Text(stringResource(id = R.string.no))
                }
            },
            backgroundColor = Color.White,
            contentColor = Color.Black
        )
    }
}
1 Answers

Check out details of Modifier.onKeyEvent usage in this answer.

In this case requestFocus has to be called from inside AlertDialog to make sure it already appeared.

In my example I use a text field to show that the modifier is not interrupted.

var displayed by remember { mutableStateOf(true) }
if (displayed) {
    val requester = remember { FocusRequester() }
    AlertDialog(
        onDismissRequest = {
            println("dismissOnClickOutside")
            displayed = false
        },
        buttons = {
            var text by remember { mutableStateOf("") }
            TextField(value = text, onValueChange = {text = it})
            LaunchedEffect(Unit) {
                requester.requestFocus()
            }
        },
        properties = DialogProperties(
            dismissOnBackPress = false,
        ),
        modifier = Modifier
            .focusRequester(requester)
            .focusable()
            .onKeyEvent {
                if (it.nativeKeyEvent.keyCode != KeyEvent.KEYCODE_BACK) {
                    return@onKeyEvent false
                }
                println("dismissOnBackPress")
                displayed = false
                false
            }
    )
}
Related