Frage: Wie erstellt man einen Rückruf von einem DialogFragment zu einem anderen Fragment? In meinem Fall sollte die betreffende Aktivität das DialogFragment überhaupt nicht kennen.
Betrachten Sie ich habe
public class MyFragment extends Fragment implements OnClickListener
Dann könnte ich irgendwann tun
DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);
Wo MyDialogFragment aussieht
protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
DialogFragment fragment = new DialogFragment();
fragment.listener = listener;
return fragment;
}
Es gibt jedoch keine Garantie dafür, dass der Listener verfügbar ist, wenn das DialogFragment angehalten und während seines Lebenszyklus fortgesetzt wird. Die einzigen Garantien in einem Fragment sind diejenigen, die über setArguments und getArguments durch ein Bundle übergeben werden.
Es gibt eine Möglichkeit, auf die Aktivität zu verweisen, wenn es sich um den Listener handeln soll:
public Dialog onCreateDialog(Bundle bundle) {
OnClickListener listener = (OnClickListener) getActivity();
....
return new AlertDialog.Builder(getActivity())
........
.setAdapter(adapter, listener)
.create();
}
Aber ich möchte nicht, dass die Aktivität auf Ereignisse wartet, ich brauche ein Fragment. Wirklich, es könnte jedes Java-Objekt sein, das OnClickListener implementiert.
Betrachten Sie das konkrete Beispiel eines Fragments, das einen AlertDialog über DialogFragment darstellt. Es hat Ja / Nein-Tasten. Wie kann ich diese Tastendrücke an das Fragment zurücksenden, das sie erstellt hat?
OnClickListener listener = (OnClickListener) getParentFragment();
in DialogFragment verwenden können und Ihr Hauptfragment die Schnittstelle wie ursprünglich implementiert.Antworten:
Die beteiligten Aktivitäten kennen das DialogFragment überhaupt nicht.
Fragmentklasse:
DialogFragment-Klasse:
quelle
setTargetFragment
undgetTargetFragment
. Die Verwendung vononActivityResult
ist etwas unklar. Es ist wahrscheinlich besser, Ihre eigene spezifische Methode im Fragment-Aufrufer zu deklarieren und diese zu verwenden, anstatt onActivityResult neu zu definieren. Aber an diesem Punkt ist alles Semantik.Die TargetFragment-Lösung scheint nicht die beste Option für Dialogfragmente zu sein, da sie möglicherweise erstellt wird,
IllegalStateException
nachdem die Anwendung zerstört und neu erstellt wurde. In diesem FallFragmentManager
konnte das Zielfragment nicht gefunden werden und Sie erhaltenIllegalStateException
eine Meldung wie die folgende:Es scheint
Fragment#setTargetFragment()
nicht für die Kommunikation zwischen einem Kind und einem Elternfragment gedacht zu sein, sondern für die Kommunikation zwischen Geschwisterfragmenten.Eine alternative Möglichkeit besteht darin, Dialogfragmente wie dieses mithilfe
ChildFragmentManager
des übergeordneten Fragments zu erstellen , anstatt die folgenden Aktivitäten zu verwendenFragmentManager
:Und mithilfe einer Schnittstelle können Sie in der
onCreate
Methode vonDialogFragment
das übergeordnete Fragment erhalten:Nach diesen Schritten müssen Sie nur noch Ihre Rückrufmethode aufrufen.
Weitere Informationen zu diesem Problem finden Sie unter folgendem Link: https://code.google.com/p/android/issues/detail?id=54520
quelle
Ich habe diese einfachen Schritte befolgt, um dieses Zeug zu machen.
DialogFragmentCallbackInterface
mit einer Methode wiecallBackMethod(Object data)
. Welche würden Sie anrufen, um Daten zu übergeben.DialogFragmentCallbackInterface
Schnittstelle in Ihrem Fragment wie implementierenMyFragment implements DialogFragmentCallbackInterface
Zum Zeitpunkt der
DialogFragment
Erstellung legen Sie Ihr aufrufendes FragmentMyFragment
als Zielfragment fest , dasDialogFragment
mithilfe vonmyDialogFragment.setTargetFragment(this, 0)
check setTargetFragment (Fragmentfragment, int requestCode) erstellt wurde.Holen Sie sich Ihr Zielfragmentobjekt in Ihr Objekt,
DialogFragment
indem Sie es aufrufengetTargetFragment()
und inDialogFragmentCallbackInterface
.Nun umwandeln. Jetzt können Sie diese Schnittstelle verwenden, um Daten an Ihr Fragment zu senden.Das ist alles erledigt! Stellen Sie einfach sicher, dass Sie diese Schnittstelle in Ihrem Fragment implementiert haben.
quelle
onActivityResult(request code, resultcode, intent)
, um das Ergebnis an fragment1 zurückzugeben. Von fragment1,setTargetFragment()
und von fragment2, VerwendunggetTargetFragment()
. Wenn Sie Eltern / Kind-Fragment zum Fragmentieren oder Aktivität zum Fragmentieren verwenden, können Sie Listener oder Rückruf verwenden, da keine Gefahr besteht, dass Eltern im Kind-Fragment verloren gehen.Vielleicht etwas spät, kann aber anderen Menschen bei der gleichen Frage helfen wie ich.
Sie können
setTargetFragment
onDialog
vor dem Anzeigen verwenden und im Dialogfeld aufrufengetTargetFragment
, um die Referenz abzurufen.quelle
Der Leitfaden Kommunikation mit anderen Fragmenten besagt, dass die Fragmente über die zugehörige Aktivität kommunizieren sollten .
quelle
Sie sollten eine
interface
in Ihrer Fragmentklasse definieren und diese Schnittstelle in ihrer übergeordneten Aktivität implementieren. Die Details finden Sie hier http://developer.android.com/guide/components/fragments.html#EventCallbacks . Der Code würde ähnlich aussehen wie:Fragment:
Aktivität:
quelle
FragmentA
und er geht davon aus, dass eine Aktivität ein istOnArticleSelectedListener
, nicht das Fragment, das ihn gestartet hat.MyFragment
Ihnen erledigt wird , können Sie zu einem regulären wechselnAlertDialog
Die richtige Methode zum Festlegen eines Listeners für ein Fragment besteht darin, es beim Anhängen festzulegen . Das Problem, das ich hatte, war, dass onAttachFragment () nie aufgerufen wurde. Nach einigen Nachforschungen stellte ich fest, dass ich getFragmentManager anstelle von getChildFragmentManager verwendet hatte
So mache ich das:
Fügen Sie es in onAttachFragment hinzu:
quelle
Laut offizieller Dokumentation:
Fragment # setTargetFragment
Fragment # getTargetFragment
So können Sie Folgendes tun:
quelle
Ich hatte ein ähnliches Problem. Die Lösung, die ich herausfand, war:
Deklarieren Sie eine Schnittstelle in Ihrem DialogFragment, wie James McCracken oben erklärt hat.
Implementieren Sie die Schnittstelle in Ihrer Aktivität (kein Fragment! Dies ist keine gute Vorgehensweise).
Rufen Sie über die Rückrufmethode in Ihrer Aktivität eine erforderliche öffentliche Funktion in Ihrem Fragment auf, die den gewünschten Job ausführt.
Somit wird es ein zweistufiger Prozess: DialogFragment -> Aktivität und dann Aktivität -> Fragment
quelle
Ich erhalte ein Ergebnis für Fragment DashboardLiveWall (aufrufendes Fragment) von Fragment LiveWallFilterFragment (empfangendes Fragment).
wo
setResult zurück zum Aufrufen von Fragmenten wie
onActivityResult
quelle
Aktualisiert:
Ich habe eine Bibliothek basierend auf meinem Kerncode erstellt, die diese Castings mit
@CallbackFragment
und für Sie generiert@Callback
.https://github.com/zeroarst/callbackfragment .
Das Beispiel zeigt das Beispiel, in dem ein Rückruf von einem Fragment an ein anderes Fragment gesendet wird.
Alte Antwort:
Ich habe eine
BaseCallbackFragment
und Anmerkung gemacht@FragmentCallback
. Es wird derzeit erweitertFragment
, Sie können es ändernDialogFragment
und es wird funktionieren. Es überprüft die Implementierungen in der folgenden Reihenfolge: getTargetFragment ()> getParentFragment ()> context (Aktivität).Dann müssen Sie es nur noch erweitern und Ihre Schnittstellen in Ihrem Fragment deklarieren und ihm die Anmerkung geben, und das Basisfragment erledigt den Rest. Die Anmerkung enthält auch einen Parameter,
mandatory
mit dem Sie bestimmen können, ob Sie das Fragment zwingen möchten, den Rückruf zu implementieren.https://gist.github.com/zeroarst/3b3f32092d58698a4568cdb0919c9a93
quelle
Kotlin Jungs hier gehen wir!
Das Problem, das wir haben, ist, dass wir eine Aktivität erstellt haben
MainActivity
, für diese Aktivität ein Fragment erstellt habenFragmentA
und jetzt ein Dialogfragment zusätzlich zumFragmentA
Aufruf erstellen möchtenFragmentB
. Wie bekommen wir die Ergebnisse vonFragmentB
zurück zuFragmentA
ohne durchzugehenMainActivity
?Hinweis:
FragmentA
ist ein Kinderfragment vonMainActivity
. Um die in erstellten Fragmente zu verwalten, verwendenFragmentA
wir das,childFragmentManager
was das tut!FragmentA
ist ein übergeordnetes Fragment vonFragmentB
, auf das wirFragmentA
von innen zugreifenFragmentB
werdenparenFragment
.Having said that, innen
FragmentA
,Hier ist das Dialogfragment
FragmentB
.Hier ist die Schnittstelle, die die beiden verbindet.
Das ist es.
quelle
Ich habe dies auf elegante Weise mit RxAndroid gelöst. Empfangen Sie einen Beobachter im Konstruktor des DialogFragments und abonnieren Sie Observable und drücken Sie den Wert, wenn der Rückruf aufgerufen wird. Erstellen Sie dann in Ihrem Fragment eine innere Klasse des Beobachters, erstellen Sie eine Instanz und übergeben Sie sie im Konstruktor des DialogFragments. Ich habe WeakReference im Observer verwendet, um Speicherverluste zu vermeiden. Hier ist der Code:
BaseDialogFragment.java
DatePickerFragment.java
MyFragment.java
Sie können den Quellcode hier sehen: https://github.com/andresuarezz26/carpoolingapp
quelle