¿Cómo mostrar un diálogo para confirmar que el usuario desea salir de una actividad de Android?
He estado tratando de mostrar un "¿Quieres salir?" Tipo de diálogo cuando el usuario intenta salir de una actividad.
Sin embargo, no puedo encontrar los ganchos API apropiados. Activity.onUserLeaveHint()
inicialmente parecía prometedora, pero no puedo encontrar una manera de detener la actividad de terminar.
- Cambio del color del botón AlertDialog.Builder
- Cómo crear un diálogo personalizado con esquinas redondeadas en android
- Animar cuadro de diálogo personalizado mediante programación
- ¿Cómo aplicar el tema ligero para la actividad y mantener el tema oscuro para los diálogos al mismo tiempo?
- Forma correcta de descartar DialogFragment mientras la aplicación está en segundo plano
- Android: Dialog de diálogo de actividad desaparece inesperadamente
- ¿Cómo se muestra un diálogo de alerta en Android?
- Cómo crear un diálogo personalizado no deseable en android
- ¿Cómo configurar el ancho y la altura de DialogFragment?
- WebView en el cuadro de diálogo
- Android: Cómo personalizar los títulos de AlertDialog, Dialog y Spinner
- ¿Cómo re tamaño de la Altura de los artículos en Spinner con opción múltiple?
- Android Resalte la tarjeta como modal de diálogo dentro de recyclerview en clic
En Android 2.0+ esto se vería así:
@Override public void onBackPressed() { new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("Closing Activity") .setMessage("Are you sure you want to close this activity?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }) .setNegativeButton("No", null) .show(); }
En las versiones anteriores sería como:
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { //Handle the back button if(keyCode == KeyEvent.KEYCODE_BACK) { //Ask the user if they want to quit new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(R.string.quit) .setMessage(R.string.really_quit) .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //Stop the activity YourClass.this.finish(); } }) .setNegativeButton(R.string.no, null) .show(); return true; } else { return super.onKeyDown(keyCode, event); } }
@Override public void onBackPressed() { new AlertDialog.Builder(this) .setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { ExampleActivity.this.finish(); } }) .setNegativeButton("No", null) .show(); }
Han modificado el código @ user919216 .. y lo han hecho compatible con WebView
@Override public void onBackPressed() { if (webview.canGoBack()) { webview.goBack(); } else { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); } }
Preferiría salir con doble pulsación en el botón de retroceso que con un diálogo de salida.
En esta solución, muestra un brindis cuando vuelve por primera vez, advirtiendo que otra prensa posterior cerrará la aplicación. En este ejemplo menos de 4 segundos.
private Toast toast; private long lastBackPressTime = 0; @Override public void onBackPressed() { if (this.lastBackPressTime < System.currentTimeMillis() - 4000) { toast = Toast.makeText(this, "Press back again to close this app", 4000); toast.show(); this.lastBackPressTime = System.currentTimeMillis(); } else { if (toast != null) { toast.cancel(); } super.onBackPressed(); } }
Token de: http://www.androiduipatterns.com/2011/03/back-button-behavior.html
Si no está seguro si la llamada a "volver" saldrá de la aplicación, o llevará al usuario a otra actividad, puede envolver las respuestas anteriores en un cheque, isTaskRoot (). Esto puede suceder si su actividad principal se puede agregar a la pila trasera varias veces, o si está manipulando el historial de la pila trasera.
if(isTaskRoot()) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { YourActivity.super.onBackPressed; } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); } else { super.onBackPressed(); }
Uso de Lambda:
new AlertDialog.Builder(this).setMessage(getString(R.string.exit_msg)) .setTitle(getString(R.string.info)) .setPositiveButton(getString(R.string.yes), (arg0, arg1) -> { moveTaskToBack(true); finish(); }) .setNegativeButton(getString(R.string.no), (arg0, arg1) -> { }) .show();
También necesita establecer un lenguaje de nivel para admitir java 8 en su gradle.build:
compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 }
Me gusta un enfoque @Gee y usarlo con fragmentos como a continuación.
@Override public void onBackPressed() { if(isTaskRoot()) { new ExitDialogFragment().show(getSupportFragmentManager(), null); } else { super.onBackPressed(); } }
Diálogo que utiliza Fragmento:
public class ExitDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(getActivity()) .setTitle(R.string.exit_question) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { getActivity().finish(); } }) .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { getDialog().cancel(); } }) .create(); } }
Esto funciona bien
@Override public void onBackPressed() { if (mExitOnBackPress) finish(); else { Toast.makeText(this, R.string.msg_confirm_exit, Toast.LENGTH_SHORT).show(); mExitOnBackPress = true; new android.os.Handler().postDelayed(new Runnable() { @Override public void run() { mExitOnBackPress = false; } }, 2000); } }
- INSTALL_FAILED_NO_MATCHING_ABIS cuando instala apk
- HorizontalScrollView dentro de ScrollView Touch Handling