Question: Comment créer un rappel d'un DialogFragment vers un autre Fragment. Dans mon cas, l'activité impliquée doit être complètement ignorante du DialogFragment.
Considérez que j'ai
public class MyFragment extends Fragment implements OnClickListener
Puis à un moment donné je pourrais faire
DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);
À quoi ressemble MyDialogFragment
protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
DialogFragment fragment = new DialogFragment();
fragment.listener = listener;
return fragment;
}
Mais il n'y a aucune garantie que l'écouteur sera là si le DialogFragment s'arrête et reprend tout au long de son cycle de vie. Les seules garanties d'un Fragment sont celles transmises via un Bundle via setArguments et getArguments.
Il existe un moyen de référencer l'activité si ce doit être l'auditeur:
public Dialog onCreateDialog(Bundle bundle) {
OnClickListener listener = (OnClickListener) getActivity();
....
return new AlertDialog.Builder(getActivity())
........
.setAdapter(adapter, listener)
.create();
}
Mais je ne veux pas que l'activité écoute les événements, j'ai besoin d'un fragment. Vraiment, il peut s'agir de n'importe quel objet Java implémentant OnClickListener.
Prenons l'exemple concret d'un Fragment qui présente un AlertDialog via DialogFragment. Il a des boutons Oui / Non. Comment puis-je renvoyer ces boutons au fragment qui les a créés?
la source
OnClickListener listener = (OnClickListener) getParentFragment();
DialogFragment à la place, et votre Fragment principal implémente l'interface comme vous l'avez fait à l'origine.Réponses:
L'activité impliquée ignore complètement le DialogFragment.
Classe de fragment:
Classe DialogFragment:
la source
setTargetFragment
etgetTargetFragment
. L'utilisation deonActivityResult
est un peu floue. Il serait probablement préférable de déclarer votre propre méthode spécifique dans l'appelant Fragment et de l'utiliser au lieu de réutiliser onActivityResult. Mais c'est toute la sémantique à ce stade.La solution TargetFragment ne semble pas être la meilleure option pour les fragments de boîte de dialogue, car elle peut se créer
IllegalStateException
après la destruction et la recréation de l'application. Dans ce cas, vousFragmentManager
ne trouvez pas le fragment cible et vous obtiendrezIllegalStateException
un message comme celui-ci:Il semble que ce
Fragment#setTargetFragment()
n'est pas destiné à la communication entre un enfant et un parent Fragment, mais plutôt à la communication entre frères et sœurs-Fragments.Une autre façon est donc de créer des fragments de dialogue comme celui-ci en utilisant le
ChildFragmentManager
du fragment parent, plutôt qu'en utilisant les activitésFragmentManager
:Et en utilisant une interface, dans la
onCreate
méthode du,DialogFragment
vous pouvez obtenir le fragment parent:La seule chose qui reste est d'appeler votre méthode de rappel après ces étapes.
Pour plus d'informations sur le problème, vous pouvez consulter le lien: https://code.google.com/p/android/issues/detail?id=54520
la source
J'ai suivi ces étapes simples pour faire ce genre de choses.
DialogFragmentCallbackInterface
avec une méthode commecallBackMethod(Object data)
. Ce que vous appelleriez pour transmettre des données.DialogFragmentCallbackInterface
interface dans votre fragment commeMyFragment implements DialogFragmentCallbackInterface
Au moment de la
DialogFragment
création, définissez votre fragment appelantMyFragment
comme fragment cible qui a crééDialogFragment
utilisezmyDialogFragment.setTargetFragment(this, 0)
check setTargetFragment (Fragment fragment, int requestCode)Obtenez votre objet de fragment cible dans votre
DialogFragment
en l'appelantgetTargetFragment()
et en leDialogFragmentCallbackInterface
convertissant en. Vous pouvez maintenant utiliser cette interface pour envoyer des données à votre fragment.C'est tout fait! assurez-vous simplement que vous avez implémenté cette interface dans votre fragment.
la source
onActivityResult(request code, resultcode, intent)
pour renvoyer le résultat à fragment1. À partir de fragment1setTargetFragment()
et à partir de fragment2, utilisezgetTargetFragment()
. Lorsque vous utilisez un fragment parent / enfant pour fragmenter ou une activité pour fragmenter, vous pouvez utiliser un écouteur ou un rappel car il n'y a aucun risque de fuite de parent dans le fragment enfant.Peut-être un peu tard, mais peut aider d'autres personnes avec la même question que moi.
Vous pouvez utiliser
setTargetFragment
surDialog
avant de montrer, et dans la boîte de dialogue, vous pouvez appelergetTargetFragment
pour obtenir la référence.la source
Le guide Communiquer avec d'autres fragments indique que les fragments doivent communiquer via l'activité associée .
la source
Vous devez définir un
interface
dans votre classe de fragment et implémenter cette interface dans son activité parente. Les détails sont décrits ici http://developer.android.com/guide/components/fragments.html#EventCallbacks . Le code ressemblerait à:Fragment:
Activité:
la source
FragmentA
et il suppose qu'une activité est unOnArticleSelectedListener
, pas le Fragment qui l'a démarré.MyFragment
vous voudrez peut-être passer à un standardAlertDialog
La manière correcte de définir un écouteur sur un fragment est de le définir lorsqu'il est attaché . Le problème que j'ai eu est que onAttachFragment () n'a jamais été appelé. Après quelques recherches, j'ai réalisé que j'avais utilisé getFragmentManager au lieu de getChildFragmentManager
Voici comment je le fais:
Attachez-le dans onAttachFragment:
la source
Selon la documentation officielle:
Fragment # setTargetFragment
Fragment # getTargetFragment
Vous pouvez donc faire ceci:
la source
J'étais confronté à un problème similaire. La solution que j'ai trouvée était:
Déclarez une interface dans votre DialogFragment comme James McCracken l'a expliqué ci-dessus.
Implémentez l'interface dans votre activité (pas fragmentée! Ce n'est pas une bonne pratique).
À partir de la méthode de rappel de votre activité, appelez une fonction publique requise dans votre fragment qui effectue le travail que vous souhaitez effectuer.
Ainsi, cela devient un processus en deux étapes: DialogFragment -> Activity puis Activity -> Fragment
la source
J'obtiens le résultat vers Fragment DashboardLiveWall (fragment d'appel) de Fragment LiveWallFilterFragment (fragment de réception) Comme ceci ...
où
setResult revient à appeler un fragment comme
onActivityResult
la source
Actualisé:
J'ai créé une bibliothèque basée sur mon code général qui génère ces castings pour vous en utilisant
@CallbackFragment
et@Callback
.https://github.com/zeroarst/callbackfragment .
Et l'exemple vous donne l'exemple qui envoie un rappel d'un fragment à un autre fragment.
Ancienne réponse:
J'ai fait une
BaseCallbackFragment
annotation@FragmentCallback
. Il s'étend actuellementFragment
, vous pouvez le changerDialogFragment
et fonctionnera. Il vérifie les implémentations dans l'ordre suivant: getTargetFragment ()> getParentFragment ()> context (activité).Ensuite, il vous suffit de l'étendre et de déclarer vos interfaces dans votre fragment et de lui donner l'annotation, et le fragment de base fera le reste. L'annotation a également un paramètre qui
mandatory
vous permet de déterminer si vous souhaitez forcer le fragment à implémenter le rappel.https://gist.github.com/zeroarst/3b3f32092d58698a4568cdb0919c9a93
la source
Les gars de Kotlin, nous y voilà!
Donc, le problème que nous avons est que nous avons créé une activité,,
MainActivity
sur cette activité, nous avons créé un fragment,FragmentA
et maintenant nous voulons créer un fragment de dialogue en plus de l'FragmentA
appelerFragmentB
. Comment pouvons-nous obtenir les résultats deFragmentB
dos àFragmentA
sans passerMainActivity
?Remarque:
FragmentA
est un fragment enfant deMainActivity
. Pour gérer les fragments créés dansFragmentA
nous utiliseronschildFragmentManager
qui fait cela!FragmentA
est un fragment parent deFragmentB
, pour accéderFragmentA
de l'intérieur,FragmentB
nous allons utiliserparenFragment
.Cela dit, à l'intérieur
FragmentA
,Voici le fragment de dialogue
FragmentB
.Voici l'interface qui relie les deux.
C'est tout.
la source
J'ai résolu cela de manière élégante avec RxAndroid. Recevoir un observateur dans le constructeur du DialogFragment et souscrire à observable et pousser la valeur lorsque le rappel est appelé. Ensuite, dans votre Fragment, créez une classe interne de l'Observer, créez une instance et passez-la dans le constructeur de DialogFragment. J'ai utilisé WeakReference dans l'observateur pour éviter les fuites de mémoire. Voici le code:
BaseDialogFragment.java
DatePickerFragment.java
MyFragment.java
Vous pouvez voir le code source ici: https://github.com/andresuarezz26/carpoolapp
la source