06 Maret 2012

Komunikasi Fragment dan Activity

Meskipun Fragment diimplementasikan sebagai sebuah obyek yang terpisah dari Activity dan bisa digunakan dalam banyak activity, sebuah instansi fragment secara langsung terikat dengan activity tempat fragment itu berada. Secara khusus, fragment bisa mengakses instansi Activity dengan getActivity() dan dengan mudah melakukan tugas seperti menemukan tampilan dalam layout activity:

View listview = getActivity().findViewById(R.id.list);
Namun sama halnya activity juga bisa memanggil metode dalam fragment dengan memperoleh sebuah referensi ke Fragment dari FragmentManager menggunakan findFragmentById() atau findFragmentByTag(), seperti contoh berikut:
ContohFragment fragment = (ContohFragment) getFragmentManager().findFragmentById(R.id.contoh_fragment);

Membuat event callback ke activity

Pada beberapa kasus, kita membutuhkan agar sebuah fragment berbagi event dengan activity. Cara yang baik untuk melakukannya adalah dengan mendefinisikan sebuah interface callback di dalam fragemnt dan activity yang menjadi host fragment juga mengimplementasikannya. Ketika activity menerima sebuah callback melalui interface, activity tersebut bisa membagikan informasi dengan fragment lain di layout sesuai kebutuhan.

Sebagai contoh, jika sebuah aplikasi berita memiliki dua fragment, fragment A untuk menampilkan daftar artikel dan fragment B untuk membaca artkikel. Kemudian fragment A harus memberitahukan activity ketika sebuah item dalam list dipilih sehingga activity bisa meminta fragment B untuk menampilkan artikel terpilih. Dalam kasus ini, interface OnArticleSelectedlistener dideklarasikan di dalam fragment A:

public static class FragmentA extends ListFragment {
     ...
     // Activity induk harus mengimplementasikan interface ini
     public interface OnArticleSelectedListener {
          public void onArticleSelected(Uri articleUri);
     }
     ...
}

kemudian activity yang menjadi host fragment menerapkan interface onArticleSelectedListener dan meng-override onArticleSelected() untuk memberitahukan fragment B mengenai event yang ada di fragment A. untuk memastikan bahwa host activity menerapkan interface ini, metode callback onAttach() (yang mana akan dipanggil sistem ketika menambahkan fragment ke activity) milik fragment A melakukan instansiasi dari OnArticleSelectedlistener dengan meng-casting Activity yang dioperkan ke onAttach():

public static class FragmentA extends ListFragment {
     OnArticleselectedListener mListener;
     ...
     @Override
     public void onAttach(Activity aktivitas) {
          super.onAttach(aktivitas);
          try {
               mListener = (OnArticleSelectedListener) aktivitas;
          } catch (ClassCastException e) {
               throw new ClassCastException(aktivitas.toString() + " Harus mengimplementasikan OnArticleSelectedListener");
          }
     }
     ...
}

Jika activity tidak mengimplementasikan interface tersebut, maka fragment akan melemparkan sebuah ClassCastException. Jika sukses, mListener akan berisi referensi ke implementasi OnArticleSelectedListener milik activity, sehingga fragment A bisa berbagi event dengan activity dengan cara memanggil metode yang didefinisikan oleh interface OnArticleSelectedListener. Sebagai contoh, jika fragment A merupakan extensi (turunan) dari ListFragment, setiap kali user mengklik sebuah item dalam list, sistem memanggil onListItemClick() dalam fragment, yang mana kemudian memanggil onArticleSelected() untuk berbagi event dengan activity:

public static class FragmentA extends ListFragment {
     OnArticleSelectedListener mListener;
     ...
     @Override
     public void onListItemClick(ListView 1, View v, int position, long id) {
          // Menambahkan ID baris item yang diklik dengan Uri dari content provider
          Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_UR1, id);
          // Mengirimkan event dan Uri ke activity induk
          mListener.onArticleSelected(noteUri);
     }
     ...
}

Parameter id yang dioperkan ke onListItemClick() adalah ID baris dari item yang di klik, yang mana digunakan oleh activity (dan fragment lain) untuk mengambil artikel dari ContentProvider milik aplikasi.

Menambahkan item ke Action Bar

Fragment yang kita buat bisa berkontribusi ke item di menu option milik activity (dan akhirnya Acton Bar) dengan cara mengimplementasikan onCreateOptionsMenu(). Agar metode ini dapat menerima panggilan, kita harus memanggil setHasOptionsMenu() selama onCreate(), untuk mengindikasikan bahwa fragment ingin menambahkan item ke menu Option (jika tidak, fragment tidak akan menerima panggilan ke onCreateOptionsMenu()).

Setiap item yang kita tambahkan ke Menu Option dari fragment juga ditambahkan ke item menu yang sudah ada. Fragment juga menerima callback ke onOptionsItemSelected() ketika sebuah menu item dipilih.

Kita juga bisa mendaftarkan sebuah tampilan pada layout fragment untuk menyediakan sebuah context menu dengan memanggil registerForContextMenu(). Ketika user membuka konteks menu, fragment menerima sebuah panggilan ke onCreateContextMenu(). ketika user memilih sebuah item, fragment menerima panggila ke onContextItemSelected().

Catatan: Meskipun fragment kita menerima sebuah callback item-dipilih untuk setiap menu yang ditambahkan fragment, activity akan lebih dulu menerima callback miliknya ketika user memilih sebuah item menu. Jika penerapan pada activity terhadap callback item-dipilih tidak menangani item yang dipilih, kemudian event dioperkan ke callback milik fragment. hal ini berlaku untuk Menu Option dan menu konteks.


4 komentar:

  1. ajarin saya fragment kang,, pusing euy

    BalasHapus
    Balasan
    1. Wah, sayang sekali. Untuk materi Andorid saya tunda dulu sampai batas waktu yang belum ditentukan. Sementara ini saya konsen ke materi Python dan keamanan komputer.

      Hapus
  2. bro kalo mau buat slider menu, trus di dalem slider menunya ada list fragment, nah masing2 dari list fragment itu menuju ke activity yg diinginkan. itu gmana cara komunikasiinnya ya?

    BalasHapus
    Balasan
    1. Aduh, sorry banget bro, gue kurang tahu. Pembelajaran android gue tunda dulu.

      Hapus