Pregunta: ¿Cómo se crea una devolución de llamada de un DialogFragment a otro Fragment? En mi caso, la actividad involucrada debe ser completamente inconsciente del DialogFragment.
Considera que tengo
public class MyFragment extends Fragment implements OnClickListener
Entonces en algún momento podría hacer
DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);
Donde se ve MyDialogFragment
protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
DialogFragment fragment = new DialogFragment();
fragment.listener = listener;
return fragment;
}
Pero no hay garantía de que el oyente estará presente si DialogFragment hace una pausa y se reanuda durante su ciclo de vida. Las únicas garantías en un Fragmento son las que se pasan a través de un Paquete a través de setArguments y getArguments.
Hay una manera de hacer referencia a la actividad si debería ser el oyente:
public Dialog onCreateDialog(Bundle bundle) {
OnClickListener listener = (OnClickListener) getActivity();
....
return new AlertDialog.Builder(getActivity())
........
.setAdapter(adapter, listener)
.create();
}
Pero no quiero que la Actividad escuche eventos, necesito un Fragmento. Realmente, podría ser cualquier objeto Java que implemente OnClickListener.
Considere el ejemplo concreto de un Fragmento que presenta un AlertDialog a través de DialogFragment. Tiene botones Sí / No. ¿Cómo puedo enviar estas pulsaciones de botón al Fragmento que lo creó?
fuente
OnClickListener listener = (OnClickListener) getParentFragment();
en DialogFragment, y tu Fragment principal implementa la interfaz como lo hiciste originalmente.Respuestas:
La actividad involucrada desconoce completamente el DialogFragment.
Clase de fragmento:
Clase DialogFragment:
fuente
setTargetFragment
ygetTargetFragment
. El uso deonActivityResult
es un poco confuso. Probablemente sería mejor declarar su propio método específico en el llamador Fragment y usarlo, en lugar de volver a utilizar onActivityResult. Pero todo es semántica en ese punto.La solución TargetFragment no parece la mejor opción para fragmentos de diálogo porque puede crearse
IllegalStateException
después de que la aplicación se destruya y se vuelva a crear. En este casoFragmentManager
no pudo encontrar el fragmento de destino y recibirá unIllegalStateException
mensaje como este:Parece que
Fragment#setTargetFragment()
no está destinado a la comunicación entre un Fragmento de padres e hijos, sino más bien a la comunicación entre Fragmentos de hermanos.Entonces, una forma alternativa es crear fragmentos de diálogo como este mediante el uso del
ChildFragmentManager
fragmento principal, en lugar de utilizar las actividadesFragmentManager
:Y al usar una interfaz, en el
onCreate
método deDialogFragment
puede obtener el fragmento primario:Lo único que queda es llamar a su método de devolución de llamada después de estos pasos.
Para obtener más información sobre el problema, puede consultar el enlace: https://code.google.com/p/android/issues/detail?id=54520
fuente
Seguí estos simples pasos para hacer esto.
DialogFragmentCallbackInterface
con algún método comocallBackMethod(Object data)
. Que llamarías para pasar datos.DialogFragmentCallbackInterface
interfaz en su fragmento comoMyFragment implements DialogFragmentCallbackInterface
En el momento de la
DialogFragment
creación, configure su fragmento de invocaciónMyFragment
como fragmento de destino que creóDialogFragment
usandomyDialogFragment.setTargetFragment(this, 0)
check setTargetFragment (Fragment fragment, int requestCode)Obtenga su objeto de fragmento de destino en su
DialogFragment
llamadagetTargetFragment()
yDialogFragmentCallbackInterface
envíelo a . Ahora puede usar esta interfaz para enviar datos a su fragmento.Eso es todo hecho! solo asegúrese de haber implementado esta interfaz en su fragmento.
fuente
onActivityResult(request code, resultcode, intent)
para devolver el resultado al fragmento1. Del fragmento1setTargetFragment()
y del fragmento2, usegetTargetFragment()
. Al usar el fragmento padre / hijo para fragmentar o la actividad para fragmentar, puede usar el oyente o la devolución de llamada, ya que no hay ningún peligro de fuga del padre en el fragmento hijo.Tal vez un poco tarde, pero puede ayudar a otras personas con la misma pregunta que yo hice.
Puede usar
setTargetFragment
onDialog
antes de mostrar, y en el diálogo puede llamargetTargetFragment
para obtener la referencia.fuente
La guía de Comunicación con otros fragmentos dice que los fragmentos deben comunicarse a través de la actividad asociada .
fuente
Debe definir un
interface
en su clase de fragmento e implementar esa interfaz en su actividad principal. Los detalles se describen aquí http://developer.android.com/guide/components/fragments.html#EventCallbacks . El código sería similar a:Fragmento:
Actividad:
fuente
FragmentA
y está asumiendo que una actividad es unOnArticleSelectedListener
, no el Fragmento que lo inició.MyFragment
ti, puedes cambiar a usar un regularAlertDialog
La forma correcta de configurar un oyente para un fragmento es configurándolo cuando está adjunto . El problema que tuve fue que onAttachFragment () nunca fue llamado. Después de investigar un poco, me di cuenta de que había estado usando getFragmentManager en lugar de getChildFragmentManager
Así es como lo hago:
Adjuntarlo en onAttachFragment:
fuente
Según la documentación oficial:
Fragmento # setTargetFragment
Fragmento # getTargetFragment
Entonces puedes hacer esto:
fuente
Estaba enfrentando un problema similar. La solución que descubrí fue:
Declare una interfaz en su DialogFragment tal como James McCracken ha explicado anteriormente.
Implemente la interfaz en su actividad (¡no fragmente! Esa no es una buena práctica).
Desde el método de devolución de llamada en su actividad, llame a una función pública requerida en su fragmento que hace el trabajo que desea hacer.
Por lo tanto, se convierte en un proceso de dos pasos: DialogFragment -> Activity y luego Activity -> Fragment
fuente
Estoy obteniendo el resultado de Fragment DashboardLiveWall (fragmento de llamada) de Fragment LiveWallFilterFragment (fragmento de recepción) De esta manera ...
dónde
setResult vuelve a llamar al fragmento como
onActivityResult
fuente
Actualizado:
Hice una biblioteca basada en mi código esencial que genera esos castings para ti usando
@CallbackFragment
y@Callback
.https://github.com/zeroarst/callbackfragment .
Y el ejemplo le da el ejemplo que envía una devolución de llamada de un fragmento a otro fragmento.
Vieja respuesta:
Hice una
BaseCallbackFragment
anotación@FragmentCallback
. Actualmente se extiendeFragment
, puede cambiarlo aDialogFragment
y funcionará. Comprueba las implementaciones en el siguiente orden: getTargetFragment ()> getParentFragment ()> context (activity).Luego solo necesita extenderlo y declarar sus interfaces en su fragmento y darle la anotación, y el fragmento base hará el resto. La anotación también tiene un parámetro
mandatory
para determinar si desea forzar el fragmento a implementar la devolución de llamada.https://gist.github.com/zeroarst/3b3f32092d58698a4568cdb0919c9a93
fuente
Kotlin chicos aquí vamos!
Entonces, el problema que tenemos es que creamos una actividad,
MainActivity
en esa actividad creamos un fragmento,FragmentA
y ahora queremos crear un fragmento de diálogo además deFragmentA
llamarloFragmentB
. ¿Cómo obtenemos los resultados desdeFragmentB
atrás hastaFragmentA
sin pasar porMainActivity
?Nota:
FragmentA
es un fragmento infantil deMainActivity
. Para gestionar los fragmentos creadosFragmentA
, usaremos elchildFragmentManager
que hace eso.FragmentA
es un fragmento padre deFragmentB
, para accederFragmentA
desde dentroFragmentB
lo utilizaremosparenFragment
.Habiendo dicho eso, adentro
FragmentA
,Aquí está el fragmento de diálogo
FragmentB
.Aquí está la interfaz que une los dos.
Eso es.
fuente
Resolví esto de una manera elegante con RxAndroid. Reciba un observador en el constructor del DialogFragment y suscríbase a observable y empuje el valor cuando se llame la devolución de llamada. Luego, en su Fragmento, cree una clase interna del Observador, cree una instancia y pásela en el constructor del DialogFragment. Usé WeakReference en el observador para evitar pérdidas de memoria. Aquí está el código:
BaseDialogFragment.java
DatePickerFragment.java
MyFragment.java
Puede ver el código fuente aquí: https://github.com/andresuarezz26/carpoolingapp
fuente