Pertanyaan: Bagaimana cara membuat panggilan balik dari DialogFragment ke Fragmen lain. Dalam kasus saya, Aktivitas yang terlibat harus benar-benar tidak menyadari DialogFragment.
Anggap saja sudah
public class MyFragment extends Fragment implements OnClickListener
Kemudian pada titik tertentu saya bisa melakukannya
DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);
Di mana MyDialogFragment terlihat seperti
protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
DialogFragment fragment = new DialogFragment();
fragment.listener = listener;
return fragment;
}
Tetapi tidak ada jaminan bahwa pendengar akan ada jika DialogFragment berhenti dan dilanjutkan melalui siklus hidupnya. Satu-satunya jaminan dalam Fragmen adalah yang diteruskan melalui Bundel melalui setArguments dan getArguments.
Ada cara untuk merujuk aktivitas jika harus menjadi pendengar:
public Dialog onCreateDialog(Bundle bundle) {
OnClickListener listener = (OnClickListener) getActivity();
....
return new AlertDialog.Builder(getActivity())
........
.setAdapter(adapter, listener)
.create();
}
Tapi saya tidak ingin Kegiatan mendengarkan acara, saya butuh Fragmen. Sungguh, itu bisa berupa objek Java yang mengimplementasikan OnClickListener.
Pertimbangkan contoh konkret dari Fragmen yang menyajikan AlertDialog melalui DialogFragment. Ini memiliki tombol Ya / Tidak. Bagaimana saya bisa mengirim tombol ini menekan kembali ke Fragmen yang membuatnya?
sumber
OnClickListener listener = (OnClickListener) getParentFragment();
di DialogFragment, dan Fragmen utama Anda mengimplementasikan antarmuka seperti yang Anda lakukan pada awalnya.Jawaban:
Aktivitas yang terlibat sama sekali tidak menyadari DialogFragment.
Kelas fragmen:
Kelas DialogFragment:
sumber
setTargetFragment
dangetTargetFragment
. PenggunaannyaonActivityResult
sedikit tidak jelas. Mungkin akan lebih baik untuk mendeklarasikan metode spesifik Anda sendiri di pemanggil Fragmen, dan menggunakannya, alih-alih membidik kembali diActivityResult. Tapi itu semua semantik pada saat itu.Solusi TargetFragment tampaknya bukan pilihan terbaik untuk fragmen dialog karena mungkin dibuat
IllegalStateException
setelah aplikasi dihancurkan dan diciptakan kembali. Dalam hal iniFragmentManager
tidak dapat menemukan fragmen target dan Anda akan mendapatkanIllegalStateException
dengan pesan seperti ini:Sepertinya
Fragment#setTargetFragment()
tidak dimaksudkan untuk komunikasi antara Fragmen anak dan orang tua, melainkan untuk komunikasi antara saudara kandung Fragmen.Jadi cara alternatif adalah membuat fragmen dialog seperti ini dengan menggunakan
ChildFragmentManager
fragmen induk, daripada menggunakan aktivitasFragmentManager
:Dan dengan menggunakan Antarmuka, dalam
onCreate
metodeDialogFragment
Anda bisa mendapatkan fragmen induk:Satu-satunya yang tersisa adalah memanggil metode panggilan balik Anda setelah langkah-langkah ini.
Untuk informasi lebih lanjut tentang masalah ini, Anda dapat memeriksa tautannya: https://code.google.com/p/android/issues/detail?id=54520
sumber
Saya mengikuti langkah-langkah sederhana ini untuk melakukan hal ini.
DialogFragmentCallbackInterface
dengan beberapa metode seperticallBackMethod(Object data)
. Yang akan Anda panggil untuk meneruskan data.DialogFragmentCallbackInterface
antarmuka dalam fragmen Anda sepertiMyFragment implements DialogFragmentCallbackInterface
Pada saat
DialogFragment
pembuatan, tetapkan fragmen pemanggilan AndaMyFragment
sebagai fragmen target yang dibuatDialogFragment
menggunakanmyDialogFragment.setTargetFragment(this, 0)
cek setTargetFragment (Fragmen fragmen, int requestCode)Dapatkan objek fragmen target Anda ke Anda
DialogFragment
dengan menelepongetTargetFragment()
dan melemparkannya keDialogFragmentCallbackInterface
. Sekarang Anda dapat menggunakan antarmuka ini untuk mengirim data ke fragmen Anda.Itu semua dilakukan! pastikan Anda telah mengimplementasikan antarmuka ini dalam fragmen Anda.
sumber
onActivityResult(request code, resultcode, intent)
untuk mengembalikan hasil ke fragmen1. Dari fragment1,setTargetFragment()
dan dari fragment2, gunakangetTargetFragment()
. Saat menggunakan fragmen induk / anak untuk fragmen atau aktivitas untuk fragmen, Anda dapat menggunakan pendengar atau panggilan balik karena tidak ada bahaya bocornya orangtua dalam fragmen anak.Mungkin agak terlambat, tetapi dapat membantu orang lain dengan pertanyaan yang sama seperti yang saya lakukan.
Anda dapat menggunakan
setTargetFragment
padaDialog
sebelum ditampilkan, dan dalam dialog Anda dapat menelepongetTargetFragment
untuk mendapatkan referensi.sumber
Panduan Berkomunikasi dengan Fragmen Lain mengatakan Fragmen harus berkomunikasi melalui Aktivitas terkait .
sumber
Anda harus mendefinisikan sebuah
interface
di kelas fragmen Anda dan mengimplementasikan antarmuka itu dalam aktivitas induknya. Detailnya diuraikan di sini http://developer.android.com/guide/components/fragments.html#EventCallbacks . Kode akan terlihat mirip dengan:Pecahan:
Aktivitas:
sumber
FragmentA
dan dia menganggap suatu kegiatan adalahOnArticleSelectedListener
, bukan Fragmen yang memulai dia.MyFragment
Anda mungkin ingin beralih menggunakan regulerAlertDialog
Cara yang benar untuk mengatur pendengar ke sebuah fragmen adalah dengan menyetelnya ketika itu dilampirkan . Masalah yang saya miliki adalah bahwa onAttachFragment () tidak pernah dipanggil. Setelah beberapa penyelidikan saya menyadari bahwa saya telah menggunakan getFragmentManager daripada getChildFragmentManager
Inilah cara saya melakukannya:
Lampirkan di onAttachFragment:
sumber
Menurut dokumentasi resmi:
Fragmen # setTargetFragment
Fragmen # getTargetFragment
Jadi Anda bisa melakukan ini:
sumber
Saya menghadapi masalah yang sama. Solusi yang saya temukan adalah:
Deklarasikan antarmuka di DialogFragment Anda seperti yang dijelaskan James McCracken di atas.
Terapkan antarmuka dalam aktivitas Anda (bukan fragmen! Itu bukan praktik yang baik).
Dari metode panggilan balik dalam aktivitas Anda, panggil fungsi publik yang diperlukan dalam fragmen Anda yang melakukan pekerjaan yang ingin Anda lakukan.
Dengan demikian, itu menjadi proses dua langkah: DialogFragment -> Activity dan kemudian Activity -> Fragment
sumber
Saya mendapatkan hasil untuk Dashboard FragmenLiveWall (memanggil fragmen) dari Fragment LiveWallFilterFragment (menerima fragmen) Seperti ini ...
dimana
setResult kembali ke memanggil fragmen suka
onActivityResult
sumber
Diperbarui:
Saya membuat perpustakaan berdasarkan kode inti saya yang menghasilkan casting untuk Anda dengan menggunakan
@CallbackFragment
dan@Callback
.https://github.com/zeroarst/callbackfragment .
Dan contoh memberi Anda contoh yang mengirim panggilan balik dari sebuah fragmen ke fragmen lain.
Jawaban lama:
Saya membuat
BaseCallbackFragment
dan membuat anotasi@FragmentCallback
. Saat ini meluasFragment
, Anda dapat mengubahnya keDialogFragment
dan akan bekerja. Ia memeriksa implementasi dengan urutan berikut: getTargetFragment ()> getParentFragment ()> konteks (aktivitas).Maka Anda hanya perlu memperluas dan mendeklarasikan antarmuka Anda dalam fragmen Anda dan memberikan penjelasannya, dan fragmen dasar akan melakukan sisanya. Anotasi juga memiliki parameter
mandatory
untuk Anda menentukan apakah Anda ingin memaksa fragmen untuk mengimplementasikan panggilan balik.https://gist.github.com/zeroarst/3b3f32092d58698a4568cdb0919c9a93
sumber
Kawan Kotlin, kita mulai!
Jadi masalah yang kita miliki adalah bahwa kita menciptakan suatu kegiatan,,
MainActivity
pada aktivitas itu kita menciptakan sebuah fragmen,FragmentA
dan sekarang kita ingin membuat fragmen dialogFragmentA
selain menyebutnyaFragmentB
. Bagaimana kita mendapatkan hasil dariFragmentB
belakangFragmentA
tanpa melaluiMainActivity
?catatan:
FragmentA
adalah fragmen anakMainActivity
. Untuk mengelola fragmen yang dibuat diFragmentA
kami akan menggunakanchildFragmentManager
yang melakukannya!FragmentA
adalah fragmen induk dariFragmentB
, untuk mengaksesFragmentA
dari dalamFragmentB
kita akan menggunakanparenFragment
.Karena itu, di dalam
FragmentA
,Inilah fragmen dialognya
FragmentB
.Berikut ini antarmuka yang menghubungkan keduanya.
Itu dia.
sumber
Saya memecahkan ini dengan cara yang elegan dengan RxAndroid. Menerima pengamat di konstruktor DialogFragment dan mendaftar untuk diamati dan mendorong nilai ketika panggilan balik dipanggil. Kemudian, di Fragmen Anda, buat kelas bagian dalam Observer, buat instance dan berikan dalam konstruktor DialogFragment. Saya menggunakan WeakReference di pengamat untuk menghindari kebocoran memori. Ini kodenya:
BaseDialogFragment.java
DatePickerFragment.java
MyFragment.java
Anda dapat melihat kode sumber di sini: https://github.com/andresuarezz26/carpoolingapp
sumber