Recibe el resultado de DialogFragment

Estoy usando DialogFragments para una serie de cosas: elegir un elemento de la lista, ingresar texto.

¿Cuál es la mejor manera de devolver un valor (es decir, una cadena o un elemento de una lista) a la actividad / fragmento de llamada?

Actualmente hago que la actividad de llamada implemente DismissListener y le doy a DialogFragment una referencia a la actividad. El OnDimiss diálogo luego llama al método OnDimiss en la actividad y la actividad toma el resultado del objeto DialogFragment. Muy desordenado y no funciona en el cambio de configuración (cambio de orientación) ya que DialogFragment pierde la referencia a la actividad.

Gracias por cualquier ayuda.

Utilice myDialogFragment.setTargetFragment(this, MY_REQUEST_CODE) desde el lugar donde muestra el cuadro de diálogo y luego, cuando finalice su diálogo, desde allí puede llamar a getTargetFragment().onActivityResult(getTargetRequestCode(), ...) , e implementar onActivityResult() en el fragmento que contiene.

Parece un abuso de onActivityResult() , especialmente porque no involucra actividades en absoluto. Pero lo he visto recomendado por personas oficiales de Google, y tal vez incluso en las demostraciones de API. Creo que es a lo que se agregaron g/setTargetFragment() .

Como puede ver aquí, hay una manera muy simple de hacerlo.

En su DialogFragment agregue un oyente de interfaz como:

 public interface EditNameDialogListener { void onFinishEditDialog(String inputText); } 

Luego, agregue una referencia a ese oyente:

 private EditNameDialogListener listener; 

Esto se usará para “activar” el (los) método (s) del oyente, y también para verificar si la Actividad / Fragmento padre implementa esta interfaz (ver a continuación).

En Activity / FragmentActivity / Fragment que “llamó” a DialogFragment simplemente implemente esta interfaz.

En su DialogFragment todo lo que necesita agregar en el punto donde desea cerrar el DialogFragment y devolver el resultado es el siguiente:

 listener.onFinishEditDialog(mEditText.getText().toString()); this.dismiss(); 

Donde mEditText.getText().toString() es lo que se pasará de vuelta a la Activity que realiza la llamada.

Tenga en cuenta que si desea devolver algo más simplemente cambie los argumentos que toma el oyente.

Finalmente, debe verificar si la interfaz fue realmente implementada por la actividad / fragmento padre:

 @Override public void onAttach(Context context) { super.onAttach(context); // Verify that the host activity implements the callback interface try { // Instantiate the EditNameDialogListener so we can send events to the host listener = (EditNameDialogListener) context; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(context.toString() + " must implement EditNameDialogListener"); } } 

Esta técnica es muy flexible y permite volver a llamar con el resultado incluso si no desea descartar el diálogo por el momento.

Hay una manera mucho más simple de recibir un resultado de un DialogFragment.

En primer lugar, en su Actividad, Fragmento o Actividad de fragmentación, debe agregar la siguiente información:

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { // Stuff to do, dependent on requestCode and resultCode if(requestCode == 1) { // 1 is an arbitrary number, can be any int // This is the return result of your DialogFragment if(resultCode == 1) { // 1 is an arbitrary number, can be any int // Now do what you need to do after the dialog dismisses. } } } 

El requestCode es básicamente tu etiqueta int para el DialogFragment que llamaste, te mostraré cómo funciona esto en un segundo. El código de resultado es el código que envía desde el DialogFragment indicando su actividad, Fragment o FragmentActivity en espera actual de lo que sucedió.

La siguiente pieza de código para entrar es la llamada a DialogFragment. Un ejemplo está aquí:

 DialogFragment dialogFrag = new MyDialogFragment(); // This is the requestCode that you are sending. dialogFrag.setTargetFragment(this, 1); // This is the tag, "dialog" being sent. dialogFrag.show(getFragmentManager(), "dialog"); 

Con estas tres líneas está declarando su DialogFragment, estableciendo un requestCode (que llamará a onActivityResult (…) una vez que se desactive el diálogo, y entonces está mostrando el diálogo. Es así de simple.

Ahora, en su DialogFragment necesita simplemente agregar una línea directamente antes de dismiss() para que envíe un resultCode de nuevo a onActivityResult ().

 getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, getActivity().getIntent()); dismiss(); 

Eso es. Tenga en cuenta que resultCode se define como int resultCode que he establecido en resultCode = 1; en este caso.

Eso es todo, ahora puede enviar el resultado de su DialogFragment a su Actividad de llamada, Fragmento o FragmentActivity.

Además, parece que esta información se publicó anteriormente, pero no se dio un ejemplo suficiente, así que pensé en proporcionar más detalles.

EDITAR 26/06/2016 Me disculpo por el código engañoso de arriba. Pero ciertamente no puede recibir el resultado de vuelta a la actividad viendo la línea:

 dialogFrag.setTargetFragment(this, 1); 

establece un Fragment objective y no Activity . Entonces, para hacer esto, necesita usar implementar InterfaceCommunicator .

En su DialogFragment establece una variable global

 public InterfaceCommunicator interfaceCommunicator; 

Crea una función pública para manejarlo

 public interface InterfaceCommunicator { void sendRequestCode(int code); } 

Luego, cuando esté listo para enviar el código nuevamente a la Activity cuando el DialogFragment ejecutarse, simplemente agregue la línea antes de dismiss(); su DialogFragment :

 interfaceCommunicator.sendRequestCode(1); // the parameter is any int code you choose. 

En su actividad ahora debe hacer dos cosas, la primera es eliminar esa única línea de código que ya no es aplicable:

 dialogFrag.setTargetFragment(this, 1); 

Luego implementa la interfaz y listo. Puedes hacer eso agregando la siguiente línea a la cláusula implements en la parte superior de tu clase:

 public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator 

Y luego @Override la función en la actividad,

 @Override public void sendRequestCode(int code) { // your code here } 

Utiliza este método de interfaz del mismo modo que lo haría con el método onActivityResult() . Excepto que el método de interfaz es para DialogFragments y el otro es para Fragments .

Bueno, es demasiado tarde para responder, pero esto es lo que hice para obtener resultados de DialogFragment . muy similar a la respuesta de @ brandon. Aquí estoy llamando a DialogFragment desde un fragmento, simplemente coloque este código donde está llamando a su diálogo.

 FragmentManager fragmentManager = getFragmentManager(); categoryDialog.setTargetFragment(this,1); categoryDialog.show(fragmentManager, "dialog"); 

donde categoryDialog es mi DialogFragment que quiero llamar y, después de esto, en su implementación de dialogfragment coloque este código donde está configurando sus datos en el bash. El valor de resultCode es 1, puede configurarlo o usar el sistema definido.

  Intent intent = new Intent(); intent.putExtra("listdata", stringData); getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent); getDialog().dismiss(); 

ahora es el momento de volver al fragmento de llamada e implementar este método. compruebe la validez de los datos o el resultado resultCode si lo desea con resultCode y resultCode in if condition.

  @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //do what ever you want here, and get the result from intent like below String myData = data.getStringExtra("listdata"); Toast.makeText(getActivity(),data.getStringExtra("listdata"),Toast.LENGTH_SHORT).show(); } 

¡Estoy muy sorprendido de que nadie haya sugerido utilizar transmisiones locales para DialogFragment para la comunicación de Activity ! Encuentro que es mucho más simple y más limpio que otras sugerencias. Esencialmente, te registras para tu Activity para escuchar las transmisiones y envías las transmisiones locales desde tus instancias de DialogFragment . Sencillo. Para obtener una guía paso a paso sobre cómo configurarlo todo, consulte aquí .

Una manera fácil que encontré fue la siguiente: Implementar este es su diálogoFragmento,

  CallingActivity callingActivity = (CallingActivity) getActivity(); callingActivity.onUserSelectValue("insert selected value here"); dismiss(); 

Y luego, en la actividad que llama el Fragmento de Diálogo, crea la función apropiada como tal:

  public void onUserSelectValue(String selectedValue) { // TODO add your implementation. Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show(); } 

La tostada es para mostrar que funciona. Trabajó para mi.

Enfoque diferente, para permitir que un Fragmento se comunique a su Actividad :

1) Defina una interfaz pública en el fragmento y cree una variable para ella

 public OnFragmentInteractionListener mCallback; public interface OnFragmentInteractionListener { void onFragmentInteraction(int id); } 

2) Emitir la actividad a la variable mCallback en el fragmento

 try { mCallback = (OnFragmentInteractionListener) getActivity(); } catch (Exception e) { Log.d(TAG, e.getMessage()); } 

3) Implemente al oyente en su actividad

 public class MainActivity extends AppCompatActivity implements DFragment.OnFragmentInteractionListener { //your code here } 

4) Anular la OnFragmentInteraction en la actividad

 @Override public void onFragmentInteraction(int id) { Log.d(TAG, "received from fragment: " + id); } 

Más información al respecto: https://developer.android.com/training/basics/fragments/communicating.html

En mi caso, necesitaba pasar argumentos a un targetFragment. Pero obtuve la excepción “Fragmento ya activo”. Así que declare una interfaz en mi DialogFragment que parentFragment implementó. Cuando parentFragment inició un DialogFragment, se establece como TargetFragment. Luego en DialogFragment llamé

  ((Interface)getTargetFragment()).onSomething(selectedListPosition); 

Solo para tenerlo como una de las opciones (ya que nadie lo mencionó aún), podrías usar un bus de eventos como Otto. Entonces, en el diálogo que haces:

 bus.post(new AnswerAvailableEvent(42)); 

Y haz que tu interlocutor (Actividad o Fragmento) se suscriba a él:

 @Subscribe public void answerAvailable(AnswerAvailableEvent event) { // TODO: React to the event somehow! }