Untuk menggunakan kembali komponen UI Fragmen, Anda harus membuatnya sebagai komponen yang sepenuhnya berfungsi sendiri dan modular yang menentukan tata letak dan perilakunya sendiri. Setelah menentukan Fragmen yang dapat digunakan kembali ini, Anda dapat mengaitkannya dengan Aktivitas dan menghubungkannya dengan logika aplikasi untuk mewujudkan keseluruhan UI gabungan.
Anda akan sering menginginkan satu Fragmen untuk berkomunikasi dengan yang lainnya, misalnya untuk mengubah konten berdasarkan peristiwa pengguna. Semua komunikasi Fragmen ke Fragmen dilakukan baik melalui ViewModel
bersama atau melalui Aktivitas terkait. Dua Fragmen tidak boleh berkomunikasi secara langsung.
Cara yang direkomendasikan untuk berkomunikasi antar fragmen adalah dengan membuat objek ViewModel
bersama. Kedua fragmen dapat mengakses ViewModel melalui Aktivitas pemuat. Fragmen dapat memperbarui data dalam ViewModel dan jika data diekspos menggunakan LiveData
, status baru akan dikirim ke fragmen lainnya selama Fragmen tersebut mengamati LiveData dari ViewModel. Untuk mengetahui cara mengimplementasikan komunikasi semacam ini, baca bagian 'Berbagi data antar-Fragmen' di panduan ViewModel.
Jika Anda tidak dapat menggunakan ViewModel bersama untuk berkomunikasi antar-Fragmen, Anda dapat menerapkan alur komunikasi secara manual menggunakan antarmuka. Namun hal ini pada akhirnya membuat lebih banyak pekerjaan untuk diterapkan dan tidak mudah digunakan kembali di Fragmen lain.
Menentukan Antarmuka
Untuk mengizinkan Fragmen berkomunikasi sampai dengan Aktivitasnya, Anda dapat menentukan antarmuka dalam class Fragmen dan mengimplementasikannya pada Aktivitas. Fragmen memperoleh implementasi antarmuka selama metode siklus proses onAttach() dan kemudian dapat memanggil metode Antarmuka untuk berkomunikasi dengan Aktivitas.
Berikut ini contoh komunikasi Fragmen ke Aktivitas:
HeadlinesFragment
Kotlin
class HeadlinesFragment : ListFragment() { internal var callback: OnHeadlineSelectedListener fun setOnHeadlineSelectedListener(callback: OnHeadlineSelectedListener) { this.callback = callback } // This interface can be implemented by the Activity, parent Fragment, // or a separate test implementation. interface OnHeadlineSelectedListener { fun onArticleSelected(position: Int) } // ... }
Java
public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener callback; public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener callback) { this.callback = callback; } // This interface can be implemented by the Activity, parent Fragment, // or a separate test implementation. public interface OnHeadlineSelectedListener { public void onArticleSelected(int position); } // ... }
AktivitasUtama
Kotlin
class MainActivity : Activity(), HeadlinesFragment.OnHeadlineSelectedListener { // ... fun onAttachFragment(fragment: Fragment) { if (fragment is HeadlinesFragment) { fragment.setOnHeadlineSelectedListener(this) } } }
Java
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ // ... @Override public void onAttachFragment(Fragment fragment) { if (fragment instanceof HeadlinesFragment) { HeadlinesFragment headlinesFragment = (HeadlinesFragment) fragment; headlinesFragment.setOnHeadlineSelectedListener(this); } } }
Sekarang fragmen dapat mengirimkan pesan ke aktivitas dengan memanggil metode onArticleSelected()
(atau metode lain dalam antarmuka) menggunakan instance mCallback
dari antarmuka OnHeadlineSelectedListener
.
Misalnya, metode berikut dalam fragmen dipanggil saat pengguna mengklik item daftar. Fragmen tersebut menggunakan antarmuka callback untuk mengirimkan peristiwa ke aktivitas induk.
Kotlin
override fun onListItemClick(l: ListView, v: View, position: Int, id: Long) { // Send the event to the host activity callback.onArticleSelected(position) }
Java
@Override public void onListItemClick(ListView l, View v, int position, long id) { // Send the event to the host activity callback.onArticleSelected(position); }
Mengimplementasikan Antarmuka
Untuk menerima callback peristiwa dari fragmen, aktivitas yang menghostingnya harus mengimplementasikan antarmuka yang ditentukan dalam class fragmen.
Misalnya, aktivitas berikut mengimplementasikan antarmuka dari contoh di atas.
Kotlin
class MainActivity : Activity(), HeadlinesFragment.OnHeadlineSelectedListener { ... fun onArticleSelected(position: Int) { // The user selected the headline of an article from the HeadlinesFragment // Do something here to display that article } }
Java
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // The user selected the headline of an article from the HeadlinesFragment // Do something here to display that article } }
Mengirim Pesan ke Fragmen
Aktivitas host dapat mengirimkan pesan ke fragmen dengan mengambil instance Fragment
dengan findFragmentById()
, kemudian langsung memanggil metode publik fragmen tersebut.
Misalnya, andaikan bahwa aktivitas yang ditunjukkan di atas dapat berisi fragmen lain yang digunakan untuk menampilkan item yang ditentukan oleh data yang ditampilkan dalam metode callback tersebut. Dalam hal ini, aktivitas dapat meneruskan informasi yang diterima dalam metode callback ke fragmen lain yang akan menampilkan item tersebut:
Kotlin
class MainActivity : Activity(), HeadlinesFragment.OnHeadlineSelectedListener { ... fun onArticleSelected(position: Int) { // The user selected the headline of an article from the HeadlinesFragment // Do something here to display that article val articleFrag = supportFragmentManager.findFragmentById(R.id.article_fragment) as ArticleFragment? if (articleFrag != null) { // If article frag is available, we're in two-pane layout... // Call a method in the ArticleFragment to update its content articleFrag.updateArticleView(position) } else { // Otherwise, we're in the one-pane layout and must swap frags... // Create fragment and give it an argument for the selected article val newFragment = ArticleFragment() val args = Bundle() args.putInt(ArticleFragment.ARG_POSITION, position) newFragment.arguments = args val transaction = supportFragmentManager.beginTransaction() // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back transaction.replace(R.id.fragment_container, newFragment) transaction.addToBackStack(null) // Commit the transaction transaction.commit() } } }
Java
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // The user selected the headline of an article from the HeadlinesFragment // Do something here to display that article ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment); if (articleFrag != null) { // If article frag is available, we're in two-pane layout... // Call a method in the ArticleFragment to update its content articleFrag.updateArticleView(position); } else { // Otherwise, we're in the one-pane layout and must swap frags... // Create fragment and give it an argument for the selected article ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit(); } } }
Untuk mempelajari implementasi Fragmen lebih lanjut, lihat Fragmen. Anda juga dapat mempelajari lebih lanjut dengan menjelajahi aplikasi contoh yang relevan.