Pytanie: W jaki sposób można utworzyć wywołanie zwrotne z DialogFragment do innego fragmentu. W moim przypadku, zaangażowana aktywność powinna być całkowicie nieświadoma DialogFragment.
Rozważ, że mam
public class MyFragment extends Fragment implements OnClickListener
Wtedy w pewnym momencie mogłem to zrobić
DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);
Gdzie wygląda MyDialogFragment
protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
DialogFragment fragment = new DialogFragment();
fragment.listener = listener;
return fragment;
}
Ale nie ma gwarancji, że odbiornik będzie w pobliżu, jeśli DialogFragment zostanie wstrzymana i wznowiona przez cały cykl życia. Jedyne gwarancje we fragmencie to te przekazywane przez Bundle za pośrednictwem setArguments i getArguments.
Istnieje sposób odniesienia się do działania, jeśli powinien to być słuchacz:
public Dialog onCreateDialog(Bundle bundle) {
OnClickListener listener = (OnClickListener) getActivity();
....
return new AlertDialog.Builder(getActivity())
........
.setAdapter(adapter, listener)
.create();
}
Ale nie chcę, aby działanie nasłuchiwało wydarzeń, potrzebuję fragmentu. Naprawdę może to być dowolny obiekt Java, który implementuje OnClickListener.
Rozważ konkretny przykład fragmentu, który przedstawia AlertDialog za pośrednictwem DialogFragment. Posiada przyciski Tak / Nie. Jak mogę wysłać te naciśnięcia przycisku z powrotem do fragmentu, który go utworzył?
źródło
OnClickListener listener = (OnClickListener) getParentFragment();
zamiast tego po prostu użyć w DialogFragment, a twój główny fragment implementuje interfejs, tak jak pierwotnie.Odpowiedzi:
Aktywność zaangażowana jest całkowicie nieświadoma DialogFragment.
Klasa fragmentu:
DialogFragment, klasa:
źródło
setTargetFragment
igetTargetFragment
. UżycieonActivityResult
jest trochę niejasne. Prawdopodobnie lepiej byłoby zadeklarować własną specyficzną metodę w obiekcie wywołującym fragmenty i użyć jej, zamiast ponownie wybierać metodę onActivityResult. Ale w tym momencie to cała semantyka.Rozwiązanie TargetFragment nie wydaje się najlepszą opcją dla fragmentów okien dialogowych, ponieważ może powstać
IllegalStateException
po zniszczeniu i odtworzeniu aplikacji. W tym przypadkuFragmentManager
nie udało się znaleźć fragmentu docelowego, a otrzymaszIllegalStateException
wiadomość taką jak ta:Wygląda na
Fragment#setTargetFragment()
to, że nie jest przeznaczony do komunikacji między dzieckiem a fragmentem rodzica, ale raczej do komunikacji między fragmentami rodzeństwa.Tak więc alternatywnym sposobem jest tworzenie fragmentów dialogów, takich jak ten, używając
ChildFragmentManager
fragmentu nadrzędnego, a nie działańFragmentManager
:Korzystając z interfejsu, w
onCreate
metodzieDialogFragment
można pobrać fragment nadrzędny:Pozostaje tylko wywołać metodę wywołania zwrotnego po wykonaniu tych czynności.
Aby uzyskać więcej informacji na temat problemu, możesz sprawdzić link: https://code.google.com/p/android/issues/detail?id=54520
źródło
Wykonałem te proste kroki, aby to zrobić.
DialogFragmentCallbackInterface
przypadku niektórych metod, takich jakcallBackMethod(Object data)
. Do którego dzwonisz, aby przekazać dane.DialogFragmentCallbackInterface
interfejs w swoim fragmencie, npMyFragment implements DialogFragmentCallbackInterface
W momencie
DialogFragment
tworzenia ustaw swój wywołujący fragmentMyFragment
jako fragment docelowy, który utworzyłDialogFragment
użyjmyDialogFragment.setTargetFragment(this, 0)
check setTargetFragment (fragment fragmentu, int requestCode)Pobierz docelowy obiekt fragmentu do swojego
DialogFragment
, wywołując gogetTargetFragment()
i rzucając do.DialogFragmentCallbackInterface
Teraz możesz użyć tego interfejsu do wysłania danych do swojego fragmentu.To wszystko gotowe! po prostu upewnij się, że zaimplementowałeś ten interfejs w swoim fragmencie.
źródło
onActivityResult(request code, resultcode, intent)
do zwracania wyniku do fragment1. Z fragmentu1setTargetFragment()
i z fragmentu2 użyjgetTargetFragment()
. Używając fragmentu rodzica / dziecka do fragmentacji lub działania do fragmentacji, możesz użyć detektora lub wywołania zwrotnego, ponieważ nie ma żadnego niebezpieczeństwa wycieku rodzica we fragmencie podrzędnym.Może trochę późno, ale może pomóc innym ludziom z tym samym pytaniem, co ja.
Możesz użyć
setTargetFragment
onDialog
przed pokazaniem, aw oknie dialogowym możesz zadzwonić,getTargetFragment
aby uzyskać odniesienie.źródło
Przewodnik dotyczący komunikacji z innymi fragmentami mówi, że fragmenty powinny komunikować się za pośrednictwem powiązanego działania .
źródło
Powinieneś zdefiniować
interface
w swojej klasie fragmentu i zaimplementować ten interfejs w jego aktywności nadrzędnej. Szczegóły opisano tutaj http://developer.android.com/guide/components/fragments.html#EventCallbacks . Kod wyglądałby podobnie do:Fragment:
Czynność:
źródło
FragmentA
i zakłada, że działanie jest fragmentemOnArticleSelectedListener
, a nie fragmentem, który go zapoczątkował.MyFragment
możesz przejść na zwykłyAlertDialog
Prawidłowym sposobem przypisania słuchacza do fragmentu jest ustawienie go w momencie dołączenia . Problem polegał na tym, że onAttachFragment () nigdy nie został wywołany. Po pewnym dochodzeniu zdałem sobie sprawę, że używałem getFragmentManager zamiast getChildFragmentManager
Oto jak to robię:
Dołącz go w onAttachFragment:
źródło
Według oficjalnej dokumentacji:
Fragment # setTargetFragment
Fragment # getTargetFragment
Więc możesz to zrobić:
źródło
Miałem podobny problem. Rozwiązanie, które znalazłem to:
Zadeklaruj interfejs w swoim DialogFragment, tak jak wyjaśnił James McCracken powyżej.
Zaimplementuj interfejs w swoim działaniu (nie fragment! To nie jest dobra praktyka).
Z metody wywołania zwrotnego w twoim działaniu, wywołaj wymaganą funkcję publiczną w swoim fragmencie, która wykonuje zadanie, które chcesz wykonać.
W ten sposób staje się procesem dwuetapowym: DialogFragment -> Aktywność, a następnie Aktywność -> Fragment
źródło
Otrzymuję wynik do Fragment DashboardLiveWall (wywołujący fragment) z Fragment LiveWallFilterFragment (odbierający fragment) W ten sposób ...
gdzie
setResult z powrotem do wywołania fragmentu takiego jak
onActivityResult
źródło
Zaktualizowano:
Stworzyłem bibliotekę opartą na moim głównym kodzie, który generuje te odlewania za pomocą
@CallbackFragment
i@Callback
.https://github.com/zeroarst/callbackfragment .
A przykład daje przykład, który wysyła wywołanie zwrotne z fragmentu do innego fragmentu.
Stara odpowiedź:
Zrobiłem
BaseCallbackFragment
i adnotację@FragmentCallback
. Obecnie się rozszerzaFragment
, możesz go zmienić naDialogFragment
i będzie działać. Sprawdza implementacje w następującej kolejności: getTargetFragment ()> getParentFragment ()> kontekst (aktywność).Następnie wystarczy go rozszerzyć i zadeklarować interfejsy w swoim fragmencie i nadać mu adnotację, a fragment podstawowy zrobi resztę. Adnotacja zawiera również parametr
mandatory
umożliwiający określenie, czy chcesz wymusić na fragmencie zaimplementowanie wywołania zwrotnego.https://gist.github.com/zeroarst/3b3f32092d58698a4568cdb0919c9a93
źródło
Chłopaki Kotlin, zaczynamy!
Więc problem polega na tym, że stworzyliśmy działanie,
MainActivity
w ramach tego działania utworzyliśmy fragment,FragmentA
a teraz chcemy utworzyć fragment okna dialogowego,FragmentA
aby go nazwaćFragmentB
. Jak uzyskać wyniki zFragmentB
powrotem doFragmentA
bez przechodzenia przezMainActivity
?Uwaga:
FragmentA
jest fragmentem podrzędnymMainActivity
. Do zarządzania utworzonymi w programie fragmentamiFragmentA
użyjemy tego,childFragmentManager
który to robi!FragmentA
jest fragmentem nadrzędnymFragmentB
, do którego dostępuFragmentA
od wewnątrzFragmentB
użyjemyparenFragment
.Mimo, że w środku
FragmentA
,Oto fragment okna dialogowego
FragmentB
.Oto interfejs łączący oba.
Otóż to.
źródło
Rozwiązałem to w elegancki sposób z RxAndroid. Odbierz obserwatora w konstruktorze DialogFragment i zasubskrybuj obserwowalne i wypchnij wartość, gdy wywoływane jest wywołanie zwrotne. Następnie w swoim fragmencie utwórz wewnętrzną klasę Observer, utwórz instancję i przekaż ją do konstruktora DialogFragment. Użyłem WeakReference w obserwatorze, aby uniknąć wycieków pamięci. Oto kod:
BaseDialogFragment.java
DatePickerFragment.java
MyFragment.java
Możesz zobaczyć kod źródłowy tutaj: https://github.com/andresuarezz26/carpoolingapp
źródło