¿Cómo puedo reutilizar un AlertDialog para Sí / No en Android?

Estoy tratando de encontrar la manera de reutilizar un cuadro de diálogo que muestra títulos personalizados, a continuación, enviar el clic Sí / No a la función que ha lanzado el cuadro de diálogo.

Tengo dos botones, Guardar y Descartar, y ambos llaman un Diálogo Sí / No, uno mostrando "¿Quieres guardar" y el otro "Descartar cambios?".

Creo que mi procedimiento es muy "sucio", pero supongo que puede funcionar, pero mi problema es la variable "View view", no sé cómo pasar de la actividad a la ventana de diálogo, por lo que puede utilizar para recordar La función que lanzó el diálogo.

Gracias de antemano, HerniHdez

.java de mi actividad (fragmento de ella)

public void open_HH_Fragment_YesNo(View view, String aux_title, String aux_function) { Bundle bundle=new Bundle(); bundle.putString("setMessage", aux_title); bundle.putString("callingFunction", aux_function); DialogFragment newFragment = new HH_Fragment_YesNo(); newFragment.setArguments(bundle); newFragment.show(getSupportFragmentManager(), "HH_Fragment_YesNo"); } public void SaveChanges(View view, String aux_YesNo) { if (aux_YesNo == "") { Toast.makeText(this, "Save changes?", Toast.LENGTH_SHORT).show(); open_HH_Fragment_YesNo(view, "Save changes?", "SaveChanges"); } else if (aux_YesNo == "Yes") { Toast.makeText(this, "Saving changes", Toast.LENGTH_SHORT).show(); } else if (aux_YesNo == "No") { Toast.makeText(this, "Save Cancelled", Toast.LENGTH_SHORT).show(); } } public void DismissChanges(View view, String aux_YesNo) { if (aux_YesNo == "") { Toast.makeText(this, "Dismiss changes?", Toast.LENGTH_SHORT).show(); open_HH_Fragment_YesNo(view, "Dismiss changes?", "DismissChanges"); } else if (aux_YesNo == "Yes") { Toast.makeText(this, "Dismiss OK", Toast.LENGTH_SHORT).show(); Close(view); } else if (aux_YesNo == "No") { Toast.makeText(this, "Dismiss Cancelled", Toast.LENGTH_SHORT).show(); } } // The dialog fragment receives a reference to this Activity through the // Fragment.onAttach() callback, which it uses to call the following methods // defined by the HH_Fragment_YesNo.YesNoDialogListener interface @Override public void onDialogPositiveClick(DialogFragment dialog, View view, String aux_function) { // User touched the dialog's positive button Toast.makeText(this, "User clicked on Yes", Toast.LENGTH_SHORT).show(); if (aux_function == "SaveChanges") { SaveChanges(view, "Yes"); } else if (aux_function == "DismissChanges") { DismissChanges(view, "Yes"); } } @Override public void onDialogNegativeClick(DialogFragment dialog, View view, String aux_function) { Toast.makeText(this, "User clicked on NO", Toast.LENGTH_SHORT).show(); if (aux_function == "SaveChanges") { SaveChanges(view, "No"); } else if (aux_function == "DismissChanges") { DismissChanges(view, "No"); } } 

.java de mi Diálogo (completo)

 public class HH_Fragment_YesNo extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); String setMessage = getArguments().getString("setMessage"); final String callingFunction = getArguments().getString("callingFuntion"); builder .setMessage(setMessage) // R.string.dialog_fire_missiles .setPositiveButton("Sí", new DialogInterface.OnClickListener() // R.string.fire { public void onClick(DialogInterface dialog, int id) { // Exit without saving mListener.onDialogPositiveClick(HH_Fragment_YesNo.this, view, callingFunction); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() // R.string.cancel { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog mListener.onDialogNegativeClick(HH_Fragment_YesNo.this, view, callingFunction); } }); // Create the AlertDialog object and return it return builder.create(); } /* The activity that creates an instance of this dialog fragment must * implement this interface in order to receive event callbacks. * Each method passes the DialogFragment in case the host needs to query it. */ public interface YesNoDialogListener { public void onDialogPositiveClick(DialogFragment dialog, View view, String aux_Function); public void onDialogNegativeClick(DialogFragment dialog, View view, String aux_Function); } // Use this instance of the interface to deliver action events YesNoDialogListener mListener; // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener @Override public void onAttach(Activity activity) { super.onAttach(activity); // Verify that the host activity implements the callback interface try { // Instantiate the NoticeDialogListener so we can send events to the host mListener = (YesNoDialogListener) activity; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(activity.toString() + " must implement NoticeDialogListener"); } } } 

Solución completa Pruebe esto

1) Interfaz Createa

 import android.content.DialogInterface; public interface AlertMagnatic { public abstract void PositiveMethod(DialogInterface dialog, int id); public abstract void NegativeMethod(DialogInterface dialog, int id); } 

2) Generalizar el método para confirmar el diálogo.

 public static void getConfirmDialog(Context mContext,String title, String msg, String positiveBtnCaption, String negativeBtnCaption, boolean isCancelable, final AlertMagnatic target) { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); int imageResource = android.R.drawable.ic_dialog_alert; Drawable image = mContext.getResources().getDrawable(imageResource); builder.setTitle(title).setMessage(msg).setIcon(image).setCancelable(false).setPositiveButton(positiveBtnCaption, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { target.PositiveMethod(dialog, id); } }).setNegativeButton(negativeBtnCaption, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { target.NegativeMethod(dialog, id); } }); AlertDialog alert = builder.create(); alert.setCancelable(isCancelable); alert.show(); if (isCancelable) { alert.setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface arg0) { target.NegativeMethod(null, 0); } }); } } 

3) Cómo usar

 getConfirmDialog(getString(R.string.logout), getString(R.string.logout_message), getString(R.string.yes), getString(R.string.no), false, new AlertMagnatic() { @Override public void PositiveMethod(final DialogInterface dialog, final int id) {} @Override public void NegativeMethod(DialogInterface dialog, int id) { } }); 

Puesto que esta página es el primer éxito en Google, y parece una tarea tan común con tan poco escrito sobre ella, compartiré la manera que he encontrado para demostrar un DialogFragment reutilizable.

El uso de interfaces se vuelve muy complicado si desea reutilizar el mismo diálogo varias veces de la misma clase, pero realizar una acción diferente cada vez. Esta solución es una manera sencilla y directa de superar ese problema sin introducir ninguna desventaja.

Edit 2017-02-25: Esta respuesta utilizaba previamente una clase Abstract para implementar confirm () y cancel (), sin embargo nuevas versiones de Android se bloquearán con el siguiente error si intenta utilizar una clase anónima como DialogFragment:

java.lang.IllegalStateException: Fragment null must be a public static class to be properly recreated from instance state.

Así que he modificado la solución para utilizar Runnables, que funciona muy bien en Java8, pero también es factible sin ella

Primero, crea una clase que implementa la creación del Diálogo mismo:

 /** * This is a reusable convenience class which makes it easy to show a confirmation dialog as a DialogFragment. * Create a new instance, call setArgs(...), setConfirm(), and setCancel() then show it via the fragment manager as usual. */ public class ConfirmationDialog extends DialogFragment { // Do nothing by default private Runnable mConfirm = new Runnable() { @Override public void run() { } }; // Do nothing by default private Runnable mCancel = new Runnable() { @Override public void run() { } }; public void setArgs(String message) { setArgs("" , message); } public void setArgs(String title, String message) { Bundle args = new Bundle(); args.putString("message", message); args.putString("title", title); setArguments(args); } public void setConfirm(Runnable confirm) { mConfirm = confirm; } public void setCancel(Runnable cancel) { mCancel = cancel; } @Override public MaterialDialog onCreateDialog(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Resources res = getActivity().getResources(); String title = getArguments().getString("title"); return new MaterialDialog.Builder(getActivity()) .title(title.equals("") ? res.getString(R.string.app_name) : title) .content(getArguments().getString("message")) .positiveText(res.getString(R.string.dialog_ok)) .negativeText(res.getString(R.string.dialog_cancel)) .callback(new MaterialDialog.ButtonCallback() { @Override public void onPositive(MaterialDialog dialog) { mConfirm.run(); } @Override public void onNegative(MaterialDialog dialog) { mCancel.run(); } }) .show(); } } 

En segundo lugar, debe hacer un método común en su Activity que muestra un DialogFragment utilizando el gestor de fragmentos:

 /** * Global method to show dialog fragment * @param newFragment the DialogFragment you want to show */ public void showDialogFragment(DialogFragment newFragment) { // DialogFragment.show() will take care of adding the fragment // in a transaction. We also want to remove any currently showing // dialog, so make our own transaction and take care of that here. FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog"); if (prev != null) { ft.remove(prev); } // save transaction to the back stack ft.addToBackStack("dialog"); newFragment.show(ft, "dialog"); } 

A continuación, puede mostrar un diálogo de confirmación desde cualquier parte de su Activity siguiente manera:

 ConfirmationDialog dialog = new ConfirmationDialog (); dialog.setArgs(stringDialogTitle, stringDialogMessage); Runnable confirm = new Runnable() { @Override public void run() { doStuff(); } }; dialog.setConfirm(confirm); showDialogFragment(dialog); 

Si tiene Java8 puede utilizar lambdas para las funciones que harán el código mucho menos verboso. Vea aquí un ejemplo.

  • AlertDialog dentro de onClickListener
  • Cuadro de mensaje para android mono
  • Mostrar el teclado virtual en AlertDialog con un WebView dentro (Android)
  • Android: AlertDialog con vista personalizada y esquinas redondeadas
  • Cómo mostrar una imagen en el cuadro de diálogo
  • Ventajas de DialogFragment sobre AlertDialog
  • Termine el diálogo y la actividad
  • Recuperación del valor de EditTexts en el constructor AlertDialog mediante Layout
  • Diálogo de alerta con un campo numérico de EditText
  • Cierre de un cuadro de diálogo de alerta personalizada al hacer clic en el botón
  • Cómo establecer el contenido de setSingleChoiceItems en onPrepareDialog?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.