Mostrar el diálogo de fragmento?

Tengo algunos fragmentos que necesitan mostrar un diálogo regular. En estos diálogos, el usuario puede elegir una respuesta de sí / no, y luego el fragmento debe comportarse en consecuencia.

Ahora, la clase Fragment no tiene un método onCreateDialog() para sobrescribir, así que supongo que tengo que implementar los diálogos afuera, en la Activity que lo contiene. Está bien, pero luego la Activity necesita informar de alguna manera la respuesta elegida al fragmento. Por supuesto, podría usar un patrón de callback aquí, por lo que el fragmento se registra en la Activity con una clase de oyente, y la Actividad informaría la respuesta a través de eso, o algo así.

Pero esto parece ser un gran desastre para una tarea simple como mostrar un diálogo “simple” de sí-no en un fragmento. Además, de esta manera mi Fragment sería menos autónomo.

¿Hay alguna manera más limpia de hacer esto?

Editar:

La respuesta a esta pregunta realmente no explica en detalle cómo uno debería usar DialogFragments para mostrar diálogos de Fragments. Entonces AFAIK, el camino a seguir es:

  1. Muestra un fragmento.
  2. Cuando sea necesario, cree una instancia de DialogFragment.
  3. Establezca el Fragmento original como el destino de este DialogFragment, con .setTargetFragment() .
  4. Muestra el DialogFragment con .show () desde el Fragment original.
  5. Cuando el usuario elige alguna opción en este DialogFragment, notifica al Fragmento original sobre esta selección (por ejemplo, el usuario hizo clic en ‘sí’), puede obtener la referencia del Fragmento original con .getTarget ().
  6. Descartar el DialogFragment.

Debería usar un DialogFragment en su lugar.

Debo dudar cautelosamente de la respuesta previamente aceptada de que usar DialogFragment es la mejor opción. El propósito (principal) previsto de DialogFragment parece ser mostrar fragmentos que son diálogos, no para mostrar fragmentos que tienen diálogos para mostrar.

Creo que usar la actividad del fragmento para mediar entre el diálogo y el fragmento es la opción preferible.

Aquí hay un ejemplo completo de un DialogFragment yes / no:

La clase:

 public class SomeDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(getActivity()) .setTitle("Title") .setMessage("Sure you wanna do this!") .setNegativeButton(android.R.string.no, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // do nothing (will close dialog) } }) .setPositiveButton(android.R.string.yes, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // do something } }) .create(); } } 

Para iniciar el diálogo:

  FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); // Create and show the dialog. SomeDialog newFragment = new SomeDialog (); newFragment.show(ft, "dialog"); 

También podría permitir que la clase implemente onClickListener y usar eso en lugar de oyentes incrustados.

Devolución de llamada a la actividad

Si desea implementar la callback, así es como se hace en su actividad:

 YourActivity extends Activity implements OnFragmentClickListener 

y

 @Override public void onFragmentClick(int action, Object object) { switch(action) { case SOME_ACTION: //Do your action here break; } } 

La clase de callback:

 public interface OnFragmentClickListener { public void onFragmentClick(int action, Object object); } 

Luego, para realizar una callback desde un fragmento, debes asegurarte de que el oyente esté conectado así:

 @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnFragmentClickListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement listeners!"); } } 

Y una callback se realiza así:

 mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter. 

Para mí, fue lo siguiente-

MyFragment:

 public class MyFragment extends Fragment implements MyDialog.Callback { ShowDialog activity_showDialog; @Override public void onAttach(Activity activity) { super.onAttach(activity); try { activity_showDialog = (ShowDialog)activity; } catch(ClassCastException e) { Log.e(this.getClass().getSimpleName(), "ShowDialog interface needs to be implemented by Activity.", e); throw e; } } @Override public void onClick(View view) { ... MyDialog dialog = new MyDialog(); dialog.setTargetFragment(this, 1); //request code activity_showDialog.showDialog(dialog); ... } @Override public void accept() { //accept } @Override public void decline() { //decline } @Override public void cancel() { //cancel } } 

MyDialog:

 public class MyDialog extends DialogFragment implements View.OnClickListener { private EditText mEditText; private Button acceptButton; private Button rejectButton; private Button cancelButton; public static interface Callback { public void accept(); public void decline(); public void cancel(); } public MyDialog() { // Empty constructor required for DialogFragment } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.dialogfragment, container); acceptButton = (Button) view.findViewById(R.id.dialogfragment_acceptbtn); rejectButton = (Button) view.findViewById(R.id.dialogfragment_rejectbtn); cancelButton = (Button) view.findViewById(R.id.dialogfragment_cancelbtn); acceptButton.setOnClickListener(this); rejectButton.setOnClickListener(this); cancelButton.setOnClickListener(this); getDialog().setTitle(R.string.dialog_title); return view; } @Override public void onClick(View v) { Callback callback = null; try { callback = (Callback) getTargetFragment(); } catch (ClassCastException e) { Log.e(this.getClass().getSimpleName(), "Callback of this class must be implemented by target fragment!", e); throw e; } if (callback != null) { if (v == acceptButton) { callback.accept(); this.dismiss(); } else if (v == rejectButton) { callback.decline(); this.dismiss(); } else if (v == cancelButton) { callback.cancel(); this.dismiss(); } } } } 

Actividad:

 public class MyActivity extends ActionBarActivity implements ShowDialog { .. @Override public void showDialog(DialogFragment dialogFragment) { FragmentManager fragmentManager = getSupportFragmentManager(); dialogFragment.show(fragmentManager, "dialog"); } } 

DialogFragment layout:

         

Como muestra el nombre dialogfragment_heightfixhiddenbtn , no pude encontrar una manera de corregir que la altura del botón inferior se redujera a la mitad a pesar de decir wrap_content , así que agregué un botón oculto para “cortar” por la mitad. Perdón por el truco.

  public void showAlert(){ AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); View alertDialogView = inflater.inflate(R.layout.test_dialog, null); alertDialog.setView(alertDialogView); TextView textDialog = (TextView) alertDialogView.findViewById(R.id.text_testDialogMsg); textDialog.setText(questionMissing); alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); alertDialog.show(); } 

donde .test_dialog es de xml personalizado

Soy un principiante y honestamente no pude encontrar una respuesta satisfactoria que pudiera entender o implementar.

Así que aquí hay un enlace externo que realmente me ayudó a lograr lo que quería. Es muy directo y fácil de seguir también.

http://www.helloandroid.com/tutorials/how-display-custom-dialog-your-android-application

ESTO ES LO QUE TRATÉ DE LOGRAR CON EL CÓDIGO:

Tengo una actividad principal que aloja un fragmento. Quería que apareciera un diálogo en la parte superior del diseño para solicitar la entrada del usuario y luego procesar la entrada en consecuencia. Ver una captura de pantalla

Esto es lo que se ve onCreateView de mi fragmento

 @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_home_activity, container, false); Button addTransactionBtn = rootView.findViewById(R.id.addTransactionBtn); addTransactionBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Dialog dialog = new Dialog(getActivity()); dialog.setContentView(R.layout.dialog_trans); dialog.setTitle("Add an Expense"); dialog.setCancelable(true); dialog.show(); } }); 

Espero que te ayude

Avíseme si hay alguna confusión. 🙂

  public static void OpenDialog (Activity activity, DialogFragment fragment){ final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager(); fragment.show(fm, "tag"); }