android - tecla - no funciona el boton de retroceso de mi celular
Detectar el botón de retroceso pero no descartar el diálogo. (7)
¿Cómo nadie ha sugerido esto?
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// Add back button listener
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) {
// getAction to make sure this doesn''t double fire
if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_UP) {
// Your code here
return true; // Capture onKey
}
return false; // Don''t capture
}
});
return dialog;
}
Tengo un fragmento de diálogo para un diálogo flotante que incluye un teclado especial que aparece cuando un usuario presiona dentro de un campo Editar Texto (el IME normal no se muestra).
Me gustaría que el teclado se cierre (visibilidad = GONE) cuando el usuario presione el botón Atrás (igual que con un servicio IME normal) pero el cuadro de diálogo permanezca visible. Sin embargo, no parece haber una manera de hacer esto tan lejos como puedo ver en mi lectura bastante extensa sobre SO y en otros lugares.
Si configuro el cuadro de diálogo para que no se pueda cancelar, entonces no me avisa onCancel () o onDismiss () porque el cuadro de diálogo no se puede cancelar.
Si configuro el diálogo para que sea cancelable, entonces recibo una notificación, pero el diálogo se cierra.
No puedo adjuntar un onKeyListener al diálogo en el fragmento porque es reemplazado por el sistema para que el fragmento pueda manejar el ciclo de vida del diálogo.
¿Hay alguna manera de hacer esto? ¿O el acceso a la detección de eventos clave ha sido completamente vallado para los fines del sistema Fragment?
Al crear el cuadro de diálogo, anule tanto onBackPressed como onTouchEvent:
final Dialog dialog = new Dialog(activity) {
@Override
public boolean onTouchEvent(final MotionEvent event) {
//note: all touch events that occur here are outside the dialog, yet their type is just touching-down
boolean shouldAvoidDismissing = ... ;
if (shouldAvoidDismissing)
return true;
return super.onTouchEvent(event);
}
@Override
public void onBackPressed() {
boolean shouldAvoidDismissing = ... ;
if (!shouldSwitchToInviteMode)
dismiss();
else
...
}
};
Como una adición a la respuesta de Juan Pedro Martínez, pensé que sería útil aclarar una pregunta específica (una que tuve) al mirar este hilo.
Si desea crear un nuevo DialogFragment y tenerlo para que el usuario solo pueda cancelarlo con el botón de retroceso, lo que elimina los toques aleatorios de la pantalla de la cancelación prematura del fragmento, entonces este es el código que usaría.
En el código al que llame DialogFragment, debe establecer la configuración cancelable en falso para que NADA descarte el fragmento, no se toque la pantalla, etc.
DialogFragment mDialog= new MyDialogFragment();
mDialog.setCancelable(false);
mDialog.show(getFragmentManager(), "dialog");
Luego, dentro de su DialogFragment, en este caso MyDaialogFragment.java, agregue el código de reemplazo de OnResume para que el diálogo escuche el botón Atrás. Cuando se presiona, ejecutará el despido () para cerrar el fragmento.
@Override
public void onResume()
{
super.onResume();
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog,
int keyCode,android.view.KeyEvent event)
{
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
// To dismiss the fragment when the back-button is pressed.
dismiss();
return true;
}
// Otherwise, do nothing else
else return false;
}
});
Ahora se llamará a su cuadro de diálogo con el "setCancelable" a falso, lo que significa que nada (sin clics externos) puede cancelarlo y apagarlo, y permitir que (desde el mismo diálogo) solo el botón Atrás lo cierre.
Ganbatte!
La mejor manera y la más limpia es anular onBackPressed () en el cuadro de diálogo que creó en onCreateDialog ().
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(getActivity(), getTheme()){
@Override
public void onBackPressed() {
//do your stuff
}
};
}
Tuve el mismo problema que tú y lo arreglé adjuntando onKeyListener al fragmento de diálogo.
En el método onResume()
de la clase que se extiende de DialogFragment, coloque estos códigos:
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog, int keyCode,android.view.KeyEvent event) {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
//Hide your keyboard here!!!
return true; // pretend we''ve processed it
}
else
return false; // pass on to be processed as normal
}
});
Aquí uno de los problemas que puede encontrar es que este código se ejecutará dos veces: uno cuando el usuario presione el botón Atrás y otro cuando lo deje para presionarlo. En ese caso, tienes que filtrar por evento:
@Override
public void onResume() {
super.onResume();
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog, int keyCode,
android.view.KeyEvent event) {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
//This is the filter
if (event.getAction()!=KeyEvent.ACTION_DOWN)
return true;
else
{
//Hide your keyboard here!!!!!!
return true; // pretend we''ve processed it
}
}
else
return false; // pass on to be processed as normal
}
});
}
Utilice la devolución de llamada onDismiss () de DialogFragment con un indicador closeActivity
private var closeActivity: Boolean = true
override fun onDismiss(dialog: DialogInterface?) {
super.onDismiss(dialog)
if (closeActivity) {
activity!!.finish()
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new Dialog(getActivity(), getTheme()) {
@Override
public void onBackPressed() {
//your code
}
};
return dialog;
}