Fragment Lifecycle — urutan yang ditentukan secara ketat dari metode callback yang dipanggil Android selama hidup Fragment: dari pembuatan (onAttach) hingga penghapusan lengkap (onDetach). Fragment memiliki siklus hidup yang lebih kompleks daripada Activity — mencakup 11 status dan 7 callback utama. Fragment Lifecycle dikelola melalui FragmentManager dan terkait erat dengan siklus hidup Activity yang menampungnya. Menurut data Google, Fragment digunakan dalam 74% aplikasi Android yang berjalan di API Level 21+, membuat pemahaman Fragment Lifecycle menjadi wajib untuk pengembangan Android profesional. Dokumentasi Android tentang Fragment Lifecycle menjelaskan semua status dan jaminan panggilan.
Poin utama
Fragment Lifecycle adalah kumpulan status dan metode yang saling terkait yang dilalui setiap instance Fragment dari saat pembuatan hingga penghancuran. Berbeda dengan Activity, siklus hidup Fragment terikat pada dua konteks: Fragment itu sendiri (hidup dari onAttach hingga onDetach) dan View-nya (hidup dari onCreateView hingga onDestroyView). Pemisahan ini adalah fitur utama Fragment, memungkinkannya bertahan dari penghancuran View saat rotasi layar tanpa menghancurkan Fragment itu sendiri.
Urutan lengkap callback Fragment:
Menurut Google, rata-rata fragmen dalam aplikasi modern melewati siklus penuh 3–5 kali per sesi pengguna (karena rotasi layar dan navigasi). Penanganan yang benar dari semua fase adalah dasar stabilitas UI.
FragmentManager mengelola Fragment melalui lima status utama, didefinisikan dalam kelas Fragment.State. Setiap status sesuai dengan kumpulan callback tertentu yang telah dijalankan.
| Status | Arti | Callback yang dijalankan |
|---|---|---|
| INITIALIZED | Fragment dibuat, tetapi View belum ada | onAttach, onCreate |
| CREATED | View dibuat, tetapi Fragment tidak terlihat | + onCreateView, onViewCreated |
| STARTED | Fragment terlihat, tetapi tidak aktif | + onStart |
| RESUMED | Fragment aktif, berinteraksi dengan pengguna | + onResume |
| DESTROYED | Fragment dihancurkan | + onDestroyView, onDestroy, onDetach |
FragmentManager memindahkan Fragment antar status tergantung pada tindakan pengguna dan peristiwa sistem. Saat menambahkan Fragment ke kontainer, ia secara berurutan melewati INITIALIZED → CREATED → STARTED → RESUMED. Saat dihapus — RESUMED → STARTED → CREATED → DESTROYED.
Status CREATED — khusus: View dapat dihancurkan (setelah onDestroyView), tetapi Fragment itu sendiri tetap dalam status CREATED (setelah onDestroyView, sebelum onDestroy). Ini memungkinkan FragmentManager menyimpan Fragment di memori tanpa View, yang diperlukan untuk bertahan dari rotasi layar.
Fragment Lifecycle dan Activity Lifecycle terkait erat, tetapi memiliki perbedaan mendasar. Fragment selalu hidup di dalam Activity, dan siklus hidupnya bergantung pada Activity inang, tetapi tidak identik dengannya.
| Aspek | Activity | Fragment |
|---|---|---|
| Jumlah callback | 7 (onCreate … onDestroy) | 11 (onAttach … onDetach) |
| Lifecycle terpisah untuk View | Tidak | Ya (viewLifecycleOwner) |
| Bertahan dari rotasi | Tidak (dihancurkan) | Ya (ViewModel + Fragment bertahan) |
| Ketergantungan pada inang | Tidak | Tergantung pada Activity Lifecycle |
| Penyimpanan status | onSaveInstanceState | onSaveInstanceState (fragmen) |
| Manajemen | Sistem | FragmentManager |
Perbedaan praktis utama: saat rotasi layar, Activity dihancurkan sepenuhnya (onDestroy) dan dibuat ulang (onCreate). Fragment saat rotasi melewati onDestroyView (View dihancurkan) → onCreateView (View dibuat ulang), tetapi Fragment itu sendiri dan ViewModel-nya tetap hidup. Ini menjadikan Fragment wadah ideal untuk logika UI yang harus bertahan dari perubahan konfigurasi.
Urutan panggilan saat rotasi layar: Activity.onPause → Fragment.onPause → Activity.onStop → Fragment.onStop → Activity.onDestroy → Fragment.onDestroyView → (Activity dihancurkan) → Activity.onCreate → Fragment.onAttach → Fragment.onCreate → Fragment.onCreateView → Fragment.onViewCreated → Activity.onStart → Fragment.onStart → Activity.onResume → Fragment.onResume.
FragmentManager — kelas pusat yang bertanggung jawab untuk menambah, menghapus, mengganti fragmen dan mengelola status mereka. FragmentManager memelihara tumpukan BackStack dan menjamin urutan callback yang benar dalam transaksi. Setiap Activity dan setiap fragmen bersarang memiliki FragmentManager sendiri.
Operasi utama FragmentManager:
BackStack — tumpukan transaksi FragmentManager. Saat tombol sistem “Kembali” ditekan, transaksi terakhir di BackStack dibatalkan (popBackStack()). Fragment yang dihapus melalui popBackStack dipulihkan. Jika BackStack kosong, menekan “Kembali” mengakhiri Activity.
Menurut Google, 78% masalah dengan Fragment (duplikasi, layar kosong, IllegalStateException) terkait dengan penggunaan FragmentManager yang tidak benar. Aturan utama: lakukan transaksi melalui commit() (asinkron) atau commitNow() (sinkron) tergantung konteks. commit() menjamin urutan yang benar dalam transaksi berganda.
Fragment mendukung mekanisme penyimpanan status sendiri melalui onSaveInstanceState, yang bekerja independen dari Activity. Fragment menyimpan status dalam Bundle, yang diteruskan ke onCreate dan onCreateView saat pemulihan.
Kapan Fragment menyimpan status:
Pendekatan modern: gunakan SavedStateHandle di ViewModel untuk menyimpan status Fragment. SavedStateHandle secara otomatis menyimpan dan memulihkan data saat rotasi layar dan process death, tanpa memerlukan onSaveInstanceState manual. Google merekomendasikan SavedStateHandle sebagai cara pilihan untuk menyimpan status UI di Fragment.
setRetainInstance (usang sejak Fragment 1.3): sebelumnya Fragment dapat dipertahankan melalui setRetainInstance(true) saat rotasi layar. Pendekatan ini telah digantikan oleh ViewModel + SavedStateHandle, yang bekerja lebih andal dan tidak memerlukan konfigurasi khusus.
viewLifecycleOwner — Lifecycle yang terikat pada View Fragment (dari onCreateView hingga onDestroyView). Ini adalah konsep yang sangat penting: langganan LiveData/Flow yang dibuat melalui viewLifecycleOwner secara otomatis dibatalkan saat penghancuran View (onDestroyView), tetapi tidak mempengaruhi Fragment itu sendiri.
Perbedaan antara viewLifecycleOwner dan lifecycle Fragment:
Mengapa ini penting: jika Anda berlangganan LiveData melalui lifecycle Fragment (this), setelah onDestroyView langganan tetap aktif dan LiveData akan mencoba memperbarui View null, menyebabkan NPE. Langganan melalui viewLifecycleOwner menjamin bahwa setelah onDestroyView tidak akan ada pembaruan UI.
Aturan: di Fragment, selalu gunakan viewLifecycleOwner untuk langganan LiveData, Flow, dan korutin yang terkait dengan UI. Untuk korutin ViewModel, gunakan viewModelScope — ini terikat pada ViewModel, bukan Fragment.
Menunjukkan inisialisasi UI yang benar dan langganan LiveData melalui viewLifecycleOwner.
class UserListFragment : Fragment() {
private val viewModel: UserListViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.fragment_user_list, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val button: Button = view.findViewById(R.id.load_button)
button.setOnClickListener { viewModel.loadUsers() }
viewModel.users.observe(viewLifecycleOwner) { users ->
Log.d("UserListFragment", "Memperbarui daftar: ${users.size} pengguna")
}
}
override fun onDestroyView() {
super.onDestroyView()
Log.d("UserListFragment", "onDestroyView: View dihancurkan")
}
}
Fragment mengembang layout di onCreateView, mengkonfigurasi UI dan berlangganan LiveData di onViewCreated. Langganan melalui viewLifecycleOwner — persyaratan wajib untuk mencegah kebocoran memori. onDestroyView mencatat penghancuran View — konfirmasi bahwa Fragment bertahan dari rotasi layar.
Menunjukkan penambahan Fragment melalui FragmentManager di Activity, penggantian dengan BackStack dan pemulihan.
class HostActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_host)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, HomeFragment())
.addToBackStack(null)
.commit()
}
}
fun openDetail(userId: String) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, DetailFragment.newInstance(userId))
.addToBackStack(null)
.commit()
}
override fun onBackPressed() {
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStack()
} else {
super.onBackPressed()
}
}
}
class DetailFragment : Fragment() {
companion object {
fun newInstance(userId: String): DetailFragment {
return DetailFragment().apply {
arguments = Bundle().apply { putString("user_id", userId) }
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val userId = arguments?.getString("user_id")
Log.d("DetailFragment", "Memuat detail pengguna: $userId")
}
}
Activity menggunakan supportFragmentManager untuk mengelola fragmen. Transaksi add() dengan BackStack menjamin bahwa saat menekan “Kembali” HomeFragment akan dipulihkan. openDetail() mengganti Fragment saat ini dengan DetailFragment dengan argumen. Pemeriksaan savedInstanceState == null mencegah duplikasi fragmen saat rotasi layar.
Penggunaan Flow dan StateFlow di Fragment dengan viewLifecycleOwner untuk pembaruan UI reaktif.
class SearchFragment : Fragment() {
private val viewModel: SearchViewModel by viewModels()
private var binding: FragmentSearchBinding? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentSearchBinding.inflate(inflater, container, false)
return binding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.searchButton?.setOnClickListener {
viewModel.search(binding?.queryInput?.text.toString())
}
viewLifecycleOwner.lifecycleScope.launch {
viewModel.searchResults.collectLatest { results ->
Log.d("SearchFragment", "Hasil pencarian: ${results.size}")
}
}
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
}
Fragment menggunakan View Binding untuk akses ke View. Korutin viewLifecycleOwner.lifecycleScope.launch secara otomatis dibatalkan saat penghancuran View. Binding dinolkan di onDestroyView untuk mencegah kebocoran memori. StateFlow menjamin keakuratan data saat pembuatan ulang View.
Pertanyaan yang sering diajukan
onCreateView — membuat dan mengembalikan View root Fragment. onViewCreated — dipanggil segera setelah pembuatan View, menjamin bahwa View sepenuhnya diinisialisasi dan siap untuk konfigurasi (findViewById, langganan). Google merekomendasikan untuk hanya mengembang layout di onCreateView, dan melakukan semua konfigurasi UI di onViewCreated.
onDestroy — Fragment dihancurkan sebagai objek (ViewModel dibersihkan, korutin dibatalkan). onDetach — callback terakhir, setelahnya Fragment terlepas dari Activity. Praktis semua sumber daya harus dibebaskan di onDestroyView (View) dan onDestroy (Fragment). onDetach — untuk membersihkan referensi ke Activity.
Fragment menghilang jika tidak ditambahkan ke FragmentManager melalui transaksi dengan penyimpanan di BackStack atau jika Activity tidak memulihkan FragmentManager di onCreate. Solusi: tambahkan Fragment secara programatis melalui supportFragmentManager.beginTransaction().add() di onCreate dengan pemeriksaan savedInstanceState == null.
Tidak. Fragment selalu terikat pada Activity melalui FragmentManager. Bahkan saat rotasi layar, Activity dibuat ulang dan Fragment terikat kembali ke Activity baru. Membuat Fragment di luar Activity tidak mungkin — konstruktor Fragment memerlukan konstruktor kosong untuk pemulihan oleh sistem.
Nested fragments (fragmen bersarang) — Fragment di dalam Fragment lain. Digunakan untuk membangun layar kompleks: panel tab, panel dengan tab, master-detail. Fragmen bersarang dikelola oleh FragmentManager anak (childFragmentManager). Google merekomendasikan untuk tidak melebihi 2 tingkat bersarang untuk menghindari masalah kinerja.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga