Google berkomitmen untuk mendorong terwujudnya keadilan rasial bagi komunitas Kulit Hitam. Lihat caranya.

Berkomunikasi dengan fragmen lain

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.

Sering kali Anda menginginkan satu Fragmen agar berkomunikasi dengan yang lainnya, misalnya untuk mengubah konten berdasarkan peristiwa pengguna. Semua komunikasi Fragmen ke Fragmen dilakukan melalui ViewModel bersama atau pun melalui Aktivitas terkait. Dua Fragmen tidak boleh berkomunikasi secara langsung.

Cara yang direkomendasikan untuk berkomunikasi antar-fragmen adalah dengan membuat ViewModel bersama. Kedua fragmen dapat mengakses ViewModel melalui Aktivitas yang memuatnya. Fragmen dapat memperbarui data dalam ViewModel dan jika data diekspos menggunakan LiveData, status baru akan dikirim ke fragmen lain selama 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 mengimplementasikan alur komunikasi secara manual menggunakan antarmuka. Namun hal ini pada akhirnya membuat lebih banyak pekerjaan untuk diimplementasikan dan tidak mudah digunakan kembali di Fragmen lain.

Menentukan antarmuka

Untuk memungkinkan Fragmen berkomunikasi sampai dengan Aktivitasnya, Anda dapat menentukan antarmuka pada class Fragmen dan mengimplementasikannya dalam Aktivitas. Fragmen memperoleh implementasi antarmuka selama metode siklus proses onAttach()-nya, lalu dapat memanggil metode Antarmuka untuk berkomunikasi dengan Aktivitas.

Berikut adalah 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 di antarmuka) menggunakan instance mCallback dari antarmuka OnHeadlineSelectedListener.

Misalnya, metode berikut ini dalam fragmen akan 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 menjadi host-nya 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 menggunakan findFragmentById(), lalu memanggil metode publik fragmen tersebut secara langsung.

Misalnya, anggaplah 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...
            supportFragmentManager.commit {
                // Replace whatever is in the fragment_container view with a new Fragment, generated
                // from the FragmentFactory, and give it an argument for the selected article
                replace<ArticleFragment>(R.id.fragment_container, null, bundleOf(ArticleFragment.ARG_POSITION to position))
                // add the transaction to the back stack so the user can navigate back
                addToBackStack(null)
            }
        }
    }
}

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 mencari aplikasi contoh FragmentBasics.