Level intermediate, pembaca diasumsikan sudah memahami dasar-dasar pembuatan aplikasi Android
Pendahuluan
Fragment adalah sebuah reuseable class yang mengimplement beberapa fitur sebuah Activity. Fragment biasanya dibuat sebagai bagian dari suatu antarmuka. Sebuah fragment harus berada di dalam sebuah activity, mereka tidak dapat berjalan sendiri tanpa adanya activity tempat mereka menempel.
Memahami Fragment
Berikut ini beberapa hal yang perlu dipahami tentang fragment:- Sebuah
Fragment
merupakan kombinasi sebuah layout XML dan kelas java yang mirip dengan sebuahActivity
. - Dengan menggunakan support library, fragment dapat mendukung hampir semua versi Android.
- Fragment dapat dipakai berulang kali didalam activity.
- Fragment merupakan komponen utuh yang memiliki view, event, dan logic (meskipun tetap membutuhkan sebuah fragment agar dapat bekerja).
Pentingnya Sebuah Fragment
Ada banyak kasus yang dapat diselesaikan menggunakan fragment, namun yang paling umum adalah:- Penggunaan Komponen View dan Logic Berulang Kali - Fragment dapat dipakai untuk menampilkan data atau melakukan event tertentu dibeberapa activity berbeda.
- Dukungan Untuk Tablet - Dibeberapa aplikasi, versi tablet dari sebuah activity memberikan layout yang berbeda dari versi handphone yang juga berbeda dari versi TV. Fragment memungkinkan activity untuk menggunakan fragment dalam membuat antarmuka sesuai dengan perangkat yang membukanya.
- Orientasi Layar - Seringkali dalam aplikasi, versi portrait dan landscape sebuah aplikasi memiliki layout yang berbeda. Fragment memungkinkan kedua orientasi tersebut untuk menggunakan tampilan yang berbeda menggunakan elemen yang sama.
Mengorganisasi Kode Fragment
Dalam aplikasi yang menggunakan banyak fragment, kita perlu selalu ingat untuk mengorganisasikan kode kita agar mengikuti best practice. Di dalam sebuah aplikasi yang memakai banyak fragment, kita harus selalu ingat fungsi dari perpindahan activity.Activity adalah navigation controller yang bertugas untuk:
- Pindah ke activity lain melalui intent.
- Menampilkan komponen navigasi seperti navigation drawer atau viewpager.
- Menampilkan dan menyembunyikan fragment tertentu menggunakan fragment manager.
- Menerima data dari intent yang mengirim data antar fragment.
- Layout dan view menampilkan konten aplikasi yang relevan.
- Melakukan management view seperti visibility atau error handling.
- Memulai network request melalui objek klien.
- Menerima dan menyimpan data dari atau ke database.
Penggunaan
Membuat Sebuah Fragment
Sebuah fragment, seperti activity, memiliki XML layout-nya sendiri dan sebuah kelas java sebagai controller dari Fragment tersebut.Layout XML yang dimiliki oleh fragment, sama seperti layout-layout lainnya dan bisa memiliki nama apa saja (selama memiliki format yang ditentukan). Anggap kita memiliki layout sebagai berikut:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
Dengan sebuah kelas Java sebagai controller:import android.support.v4.app.Fragment;
public class FooFragment extends Fragment {
// Method onCreateView dipanggil saat Fragment harus menampilkan layoutnya // dengan membuat layout tersebut secara manual lewat objek View atau dengan // membaca file XML
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
// Layout tampilan untuk fragment ini
return inflater.inflate(R.layout.fragment_foo, parent, false);
}
// Method ini dipanggil sesaat setelah onCreateView().
// Semua pembacaan view dan penambahan listener dilakukan disini (atau // bisa juga didalam onCreateView)
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// EditText etFoo = (EditText) view.findViewById(R.id.etFoo);
}
}
Menempelkan Fragment Kedalam Activity
Ada dua cara untuk menempelkan sebuah fragment ke activity: secara dinamis menggunakan Java dan secara statis (manual) dengan XML.Sebelum menempelkan fragment dari library "support" didalam Activity, pastikan bahwa Activity sudah meng-extends
FragmentActivity
atau AppCompatActivity
yang memiliki fragment manager untuk semua versi Android.import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
// ...
}
Menempelkan Fragment Secara Statis (Manual)
Untuk menempelkan fragment secara statis (manual), cukup tambahkan elemenfragment
ke dalam layout milik sebuah activity dimana kita menentukan nama dari Fragment yang akan ditampilkan lewat elemen tersebut.<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:name="com.example.android.FooFragment"
android:id="@+id/fooFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Catatan:- Sesuaikan path FooFragment untuk mengikuti package name aplikasi kita.
- Kita tidak dapat mengganti fragment yang ditambahkan secara statis lewat file XML menggunakan FragmentTransaction (baca di bawah). Kita hanya bisa mengganti fragment yang ditempelkan secara dinamis.
Menempelkan Fragment Secara Dinamis
Cara yang kedua ialah dengan menempelkan fragment secara dinamis menggunakan Java dengan melaluiFragmentManager
. Kelas FragmentManager
dan kelas FragmentTransaction memungkinkan kita untuk menambah, menghapus dan menimpa fragment yang ada di layout saat activity sedang aktif. Dalam kasus ini kita membutuhkan sebuah container (biasanya menggunakan
FrameLayout
) ke dalam activity dimana kita bisa menempelkan sebuah fragment.<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/your_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
lalu kita dapat menggunakan FragmentManager untuk membuat sebuah FragmentTransaction yang mengijinkan kita menambah fragment ke FrameLayout
di atas:// Memulai transaksi
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// mengganti isi container dengan fragment baru
ft.replace(R.id.your_placeholder, new FooFragment());
// atau ft.add(R.id.your_placeholder, new FooFragment());
// mulai melakukan hal di atas (jika belum di commit maka proses di atas belum dimulai)
ft.commit();
Jika sebuah fragment harus selalu ada di dalam activity, gunakan XML
untuk meanmpilkannya secara statis namun saat menemukan kasus yang lebih
kompleks pastikan untuk menggunakan pendekatan menggunakan Java. Fragment Lifecycle
Fragment memiliki banyak method yang dapat di override seperti halnya Activity:onAttach()
dipanggil saat sebuah fragment terhubung ke activity.onCreate()
diapnggil saat sebuah fragment dibuat (objeknya di memori).onCreateView()
dipanggil saat fragment sudah siap membaca sebuah layout.onViewCreated()
dipanggil setelahonCreateView()
dan memastikan layout yang dibaca fragment adalahnon-null
. Semua pengaturan view seperti pembacaan findViewById, menambah onClickListener dapat dilakukan di sini.onActivityCreated()
dipanggil setelah activity pembaca sudah menyelesaikanonCreate()
-nya.onStart()
dipanggil setelah fragment siap untuk ditampilkan di layar.onResume()
- Dipakai untuk melakukan pembacaan data yang lebih "rumit" seperti lokasi, sensor, dll.onPause()
- Tempat melepas data "rumit". Lakukan commit di sini.onDestroyView()
dipanggil saat layout sebuah fragment akan dihapus dari memori, namun fragmentnya masih ada di memori.onDestroy()
dipanggil jika fragment sudah tidak dipakai.onDetach()
dipanggil saat fragment tidak lagi terhubung ke sebuah activity.
Yang paling sering di override adalah
onCreateView
karena hampir setiap fragment akan memerlukan sebuah layout, onCreate
saat ingin menginisialisasi data dan onActivityCreated
untuk menyiapkan sesuatu saat Activity sudah sempurna dimuat.Berikut ini contoh bagaimana kita bisa memanfaatkan event lifecycle milik fragment:
public class SomeFragment extends Fragment {
ThingsAdapter adapter;
FragmentActivity listener;
// Event ini dipanggil pertam akali sebelum pembuatan fragment atau pembacaan
// layout lain. Method onAttach dipanggil saat sebuah instance Fragment
// terhuubng dengan sebuah Activity.
// Method ini tidak berarti Activity sudah dimuat sempurna.
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof Activity){
this.listener = (FragmentActivity) context;
}
}
// Event ini dipanggil kedua, sebelum layout dibaca dan method onCreate
// didalam Fragment dipanggil saat instance Fragment tersebut sebuah dibuat
// atau dibuat ualng.
// Gunakan onCreate untuk pengaturan standar lainnya yang tidak mensyaratkan
// activity dimuat terlebih dahulu.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<Thing> things = new ArrayList<Thing>();
adapter = new ThingsAdapter(getActivity(), things);
}
// Method onCreateView dipanggil saat Fragment harus membuat layoutnya
// menggunakan objek View di Java secara dinamis atau membacanya dari XML.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_some, parent, false);
}
// Event ini dipanggil sesaat setelah onCreateView().
// onViewCreated hanya dipanggil jika sebuah view dari onCreateView() tidak
// null.
// Pembacaan findViewById atau listener lainnya dapat dilakukan di sini.
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
ListView lv = (ListView) view.findViewById(R.id.lvSome);
lv.setAdapter(adapter);
}
// Method ini dipanggil saat fragment sudah tidak terhubung dengan Activity.
// Semua reference yang dipasang di onAttach harus dilepas disini untuk
// menghindari memory leak.
@Override
public void onDetach() {
super.onDetach();
this.listener = null;
}
// method ini dipanggil saat method onCreate() milik Activity yang memanggilnya
// sudah sempurna dijalankan.
// Dimethod ini kita bisa membaca objek miliki Activity berdasarkan viewnya.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
Mencari Fragment yang Sudah Dibuat
Seringkali kita perlu mencari sebuah instance fragment didalam layout activity. Ada beberapa cara yang dapat kita gunakan untuk mencari sebuah instance fragment yang sebelumnya telah dibuat:- ID - Mencari fragment dengan memanggil
findFragmentById
diFragmentManager
- Tag - Mencari fragment dengan memanggil
findFragmentByTag
diFragmentManager
- Pager - Mencari fragment dengan memanggil
getRegisteredFragment
diPagerAdapter
Mencari Fragment Berdasarkan ID
Jika fragment ditempelkan secara manual di XML (menggunakan elemen<fragment>
) dengan sebuah android:id
misalnya fragmentDemo
maka kita bisa membaca fragment ini berdasarkan id yang dia miliki menggunakan findFragmentById
pada FragmentManager
:public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
DemoFragment fragmentDemo = (DemoFragment)
getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);
}
}
}
Mencari Fragment Berdasarkan Tag
Jika fragment ditambah secara dinamis maka kita bisa mencarinya menggunakanfindFragemntByTag
pada FragmentManager
:public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// Kita tambahkan dulu sebuah fragment dengan sebuah TAG
getSupportFragmentManager().beginTransaction().
replace(R.id.flContainer, new DemoFragment(), "SOMETAG").
commit();
// Kita bisa membaca fragment di atas dengan memanfaatkan TAG yang
// telah diberikan
DemoFragment fragmentDemo = (DemoFragment)
getSupportFragmentManager().findFragmentByTag("SOMETAG");
}
}
}
Mencari Fragment didalam Pager
Jika sebuah fragment ditambahkan secara dinamis menggunakanViewPager
dan sebuah FragmentPagerAdapter maka kita bisa mencari fragment di dalamnya dengan menggantinya menjadi SmartFragmentStatePagerAdapter
seperti dijelaskan di panduan ViewPager ini. Sekarang dengan adapter yang sudah di upgrade, kita bisa dengan mudah mengakses fragment di dalamnya menggunakan getRegisteredFragment
:// returns first Fragment item within the pager
adapterViewPager.getRegisteredFragment(0);
Ingat bahwa ViewPager
membaca fragment seperti ListView
dengan me-recycle
fragment saat mereka tampil di layar. Jika kita mencoba mengakses
fragment yang tidak ada di layar, maka pembacaan ini bisa mendapatkan
data null
.Berkomunikasi dengan Fragment (Kirim Data)
Fragment pada umumnya hanya berkomunikasi secara langsung dengan activity yang menampilkannya. Fragment dapat berkomunikasi melalui activity yang membacanya untuk mengatur data input dan output dari fragment tersebut ke fragment lain atau activity lain. Cukup anggap Activity sebagai controller yang mengatur interaksi antar fragment yang dia baca.Beberapa pengecualian untuk teori di atas adalah dialog fragments yang ditampilkan dari dalam fragment lain atau nested child fragments. Kedua kasus ini adalah situasi di mana sebuah fragment memiliki nested child fragments dan boleh berkomunikasi dengan parent-nya langsung (yang merupakan sebuah fragment) tanpa melalui activity tempat fragment utama menempel.
Hal penting lainnya yang perlu diingat adalah fragment tidak semestinya berkomunikasi dengan fragment lain secara langsung dan sebaiknya hanya berkomunikasi melalui parent activity.
Ada tiga cara sebuah fragment dan sebuah activity dapat berkomunikasi:
- Bundle - Activity dapat membuat sebuah fragment dan menambahkan arguments
- Methods - Activity dapat memanggil method di dalam instance fragment
- Listener - Fragment dapat memanggil event listener di dalam sebuah activity lewat sebuah interface.
- Activity dapat menginisialisasi fragment dengan data saat dibuat.
- Activity dapat mengirim data ke fragment menggunakan method yang ada di dalam instance si fragment.
- Fragment dapat berkomunikasi dengan parent activity menggunakan sebuah interface dan listener.
- Fragment harus mengirimkan data ke fragment lain melalui parent activity-nya.
- Fragment dapat mengirim data dari dan ke dalam dialog fragment secara langsung.
- Fragment dapat memiliki nested child fragment.
Fragment dengan Argument
Dalam beberapa kasus, fragment kita mungkin perlu meminta argument tertentu. Pola yang paling umum ialah dengan membuat method static bernamanewInstace
untuk membuat sebuah Fragment dengan
argument. Hal ini karena kita hanya boleh memiliki sebuah constructor
tanpa argument papun. Di dalam method newInstance
ini kita dapat memanggil setArguments
:public class DemoFragment extends Fragment {
// Membuat sebuah fragment engan sebuah int dan title
// DemoFragment.newInstance(5, "Hello");
public static DemoFragment newInstance(int someInt, String someTitle) {
DemoFragment fragmentDemo = new DemoFragment();
Bundle args = new Bundle();
args.putInt("someInt", someInt);
args.putString("someTitle", someTitle);
fragmentDemo.setArguments(args);
return fragmentDemo;
}
}
Kode di atas memberikan argument ke fragment untuk dipanggil nanti di dalam
onCreate
. Kita dapat mengakses argument ini nanti menggunakna:public class DemoFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Ambil lagi argument tadi
int SomeInt = getArguments().getInt("someInt", 0);
String someTitle = getArguments().getString("someTitle", "");
}
}
Sekarang kita bisa membaca sebuah fragment secara dinamis di dalam sebuah Activity menggunakan:
// Di dalam activity
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
DemoFragment fragmentDemo = DemoFragment.newInstance(5, "my title");
ft.replace(R.id.your_placeholder, fragmentDemo);
ft.commit();
Pola ini membuat proses pengiriman fragment ke fragment menjadi lebih jelas. Method Fragment
Jika sebuah activity mengingimkan sebuah fragment melakukan suatu aksi setelah dibuat, cara paling mudah ialah dengan memanggil method dari dalam instance si fragment. Di dalam fragment, buat sebuah method:public class DemoFragment extends Fragment {
public void doSomething(String param) {
// lakukan sesuatu
}
}
lalu di dalam activity, panggil method tadi:public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DemoFragment fragmentDemo = (DemoFragment)
getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);
fragmentDemo.doSomething("some param");
}
}
maka activity dapat berkomunikasi secara langsung dengan si fragment menggunakan cara ini.Fragment Listener
Jika fragment perlu berkomunikasi dengan parent activity-nya secara langsung, maka fragment tersebut perlu mendefinisikan sebuah interface dan meminta activity untuk mengimplement interface ini.import android.support.v4.app.Fragment;
public class MyListFragment extends Fragment {
// ...
// Buat objek untuk listener
private OnItemSelectedListener listener;
// Definisikan event yang harus ada di dalam sebuah interface
public interface OnItemSelectedListener {
// Dapat berupa event apapun
public void onRssItemSelected(String link);
}
// Simpan listener yang akan terpanggil dari suatu event setelah fragment-nya ter-attach di activity
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnItemSelectedListener) {
listener = (OnItemSelectedListener) context;
} else {
throw new ClassCastException(context.toString()
+ " must implement MyListFragment.OnItemSelectedListener");
}
}
// Sekarang kita dapat memanggil event dari dalam fragment
public void onSomeClick(View v) {
listener.onRssItemSelected("some link");
}
}
dan di dalam activity kita perlu meng-implement listener OnItemSelectedListener
:import android.support.v7.app.AppCompatActivity;
// Activity perlu mengimplement listener di atas untuk meng-handle event
public class RssfeedActivity extends AppCompatActivity implements MyListFragment.OnItemSelectedListener {
// Dapat berupa fragment apapun, DetailFragment hanya contoh
DetailFragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rssfeed);
// membaca fragment menggunakan id
fragment = (DetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.detailFragment);
}
// Sekarang kita bisa mendefinisikan aksi yang perlu dilakukan oleh activity
// saat fragment dijalankan
// Kita meng-implement method yang didefinisikan didalam interface `OnItemSelectedListener` yang sebelumnya kita buat di dalam Fragment
@Override
public void onRssItemSelected(String link) {
if (fragment != null && fragment.isInLayout()) {
fragment.setText(link);
}
}
}
Memahami FragmentManager
FragmentManager bertugas untuk melakukan manajemen fragment saat aplikasi berjalan termasuk didalamnya menambah, menghapus, menampilkan atau melakukan navigasi antar fragment. Seperti terlihat pada contoh-contoh di atas, fragment manager juga dapat dipakai untuk mencari fragment di dalam sebuah activity. Method penting dari FragmentManager adalah sebagai berikut:Method | Deskripsi |
---|---|
addOnBackStackChangedListener | Menambah listener untuk back stack fragment. |
beginTransaction() | Membuat transaksi baru untuk merubah fragment saat program berjalan. |
findFragmentById(int id) | Mencari fragment berdasarkan id yang biasanya ditulis di layout XML milik activity. |
findFragmentByTag(String tag) | Mencari fragment berdasarkan tag jika menambah fragment secara dinamis. |
popBackStack() | Menghapus sebuah fragment dari backstack. |
executePendingTransactions() | Memaksa transaksi untuk diaplikasikan. |
ActionBar Menu Items dan Fragments
Dalam beberapa kasus kita ingin agar sebuah fragment memiliki menu item sendiri yang hanya tampil saat fragment tersebut aktif. Kasus ini dapat diselesaikan dengan menambah methodonCreateOptionsMenu
ke fragment tersebut. Cara kerjanya mirip dengan yang ada di Activity:@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
}
Kita juga harus memberitahu fragment bahwa ia memiliki menu item di dalam onCreate
:@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Klik dapat ditanganai seperti pada activity dengan method onOptionsItemSelected
:@Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection
switch (item.getItemId()) {
case R.id.edit_item:
// do s.th.
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Navigasi Antar Fragments
Ada beberapa method untuk melakukan navigasi antar fragment yang berbeda di dalam satu Activity. Solusi-solusi utamanya adalah:There are several methods for navigating between different fragments within a single Activity. The primary options are:
- TabLayout - Tabs di atas
- Fragment Navigation Drawer - Menyeret menu navigasi dari samping
- ViewPager - Geser antar fragment untuk pindah
Manajemen Backstack Fragment
Catatan untuk semua transaksi Fragment disimpan oleh setiap Activity melalui FragmentManager. Saat diatur dengan benar, pengguna dapat menghapus fragment terakhir yang ditambahkan saat tombol back ditekan (tidak langsung keluar dari activity). Cukup panggil addToBackstack disetiap FragmentTransaction
:// Membuat transaksi
FragmentTransaction fts = getSupportFragmentManager().beginTransaction();
// Mengganti konten f1Container dengan FirstFragment
fts.replace(R.id.flContainer, new FirstFragment());
// Menambah transaksi ini ke backstack
fts.addToBackStack("optional tag");
// Commit the changes
fts.commit();
Kita juga dapat menghapus fragment terakhir yang ditambahkan lewat kode Java menggungkan objek manager:FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
}
Dengan teknik ini kita dapat mencatat urutan fragmen yang tampil
secara dinamis dan memungkinkan pengguna untuk pindah ke
fragment-fragment sebelumnya.Hide vs Replace
Dapat contoh-contoh di atas, kita memanggiltransaction.replace(...)
untuk membaca fragment secara dinamis dengan menghapus fragment yang
sebelumnya sudah ada di container. Method ini akan memanggil onStop
dan onDestroy
untuk fragment sebelumnya lalu membuat fragment baru di container tadi.
Cara ini baik karena kita bisa membersihkan memori dan membuat UI lebih
smooth. Namun, dalam banyak kasus kita ingin akan
fragment-fragment tersebut tetap ada di container dengan menampilkannya
dengan mengatur visibility-nya saja. Dengan begini semua fragment terlihat seperti saat terakhir sebelum pindah fragment:// Di dalam activity
private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
fragmentA = FragmentA.newInstance("foo");
fragmentB = FragmentB.newInstance("bar");
fragmentC = FragmentC.newInstance("baz");
}
}
protected void displayFragmentA() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// menghapus fragment sebelumnya
ft.replace(R.id.flContainer, fragmentA);
ft.commit();
}
teknik di bawah menambah add
, show
, dan hide
di FragmentTransaction
:// ...onCreate masih sama
// Ganti cara perpindahannya
protected void displayFragmentA() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (fragmentA.isAdded()) { // jika fragment sudah ada di container tampilkan
ft.show(fragmentA);
} else { // jika tidak ada tambahkan
ft.add(R.id.flContainer, fragmentA, "A");
}
// Sembunyikan fragment B
if (fragmentB.isAdded()) { ft.hide(fragmentB); }
// Sembunyikan fragment C
if (fragmentC.isAdded()) { ft.hide(fragmentC); }
// Commit perubahan
ft.commit();
}
Dengan teknik ini ketiga fragment tetap ada di container dan perpindahannya hanya dilakukan dengan mengatur visibility-nya saja. Fragment di dalam Fragment
Terkadang kita perlu menambah fragment di dalam fragment yang lai. Sejak Andorid 4.2 kita memiliki kemampuan tersebut. Fragment yang ditempelkan ke dalam fragment lain disebut dengan child fragment. Situasi seperti ini terjadi saat kita ingin membuat fragment menampilkan tabs saat menggunakan teknik navigasi lain seperti ViewPager atau Navigation Drawer.Kekurangan child fragment adalah mereka harus ditambahkan secara dinamis tidak bisa menggunakan tag
<fragment>
. Untuk menambahkan fragment ke dalam fragment lain, kita memerlukan <FragmeLayout>
atau sebuah ViewPager (yang nantinya akan membaca fragment secara dinamis, dimasa mendatang kita akan membahasnya) ke res/layout/fragment_parent.xml
(ingat bahwa file ini hanya contoh, sesuaikan dengan layout yang
dimiliki oleh fragment dimana kita ingin menambah fragment lain di
dalamnya):<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I am the parent fragment" />
<FrameLayout
android:id="@+id/child_fragment_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Lihat di FrameLayout
di atas memiliki id @+id/child_fragment_container
dimana child fragment akan kita tempelkan. Kita dapat menempelkan
fragment ke FrameLayout ini melalui kelas Java si Fragment-nya:// Kelas Fragment utama tempat kita ingin menempelkan fragment lain
public class ParentFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_parent, container, false);
}
}
// Kelas Fragment yang ingin ditampilkan ke fragment di atas
public class ChildFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Need to define the child fragment layout
return inflater.inflate(R.layout.fragment_child, container, false);
}
}
Di dalam Fragment Utama, kita akan menambahkan ChildFragment menggunakan method getChildFragmentManager
:// Kelas Fragment utama tempat kita ingin menempelkan fragment lain
public class ParentFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_parent, container, false);
}
// Dipanggil setelah onCreateView() sukses.
// onViewCreated() hanya dipanggil jika view dari onCreateView() tidak null
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
insertNestedFragment();
}
// Tambah child fragment secara dinamis
private void insertNestedFragment() {
Fragment childFragment = new ChildFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.child_fragment_container, childFragment).commit();
}
}
Catat bahwa kita harus selalu menggunakan getChildFragmentManager saat berinteraksi dengan nested fragment dan tidak menggunakan getSupportFragmentManager
. Baca stackoverflow post ini untuk penjelasan perbedaan antara keduanya.Di dalam child fragment, kita dapat menggunakan
getParentFragment()
untuk mendapat reference ke parent fragment, seperti getActivity()
jika di fragment biasa yang memberikan akses ke parent Activity. Menangani Configuration Changes
Saat bekerja dengan fragment, kita juga harus menangani configuration changes misalnya saat layar diputar atau saat activity dihapus. Artikel selanjutnya kita akan membahas hal ini. Stay tuned dan ingatkan kalau terlalu lama.Diterjemahkan dari Creating and Using Fragments
Reference :
codepolitan
Membuat dan Menggunakan Fragment
Creating and Using Fragments
No comments:
Post a Comment