Android Fragments Explained - Complete Developer Guide with Kotlin
In this tutorial, you'll learn Android Fragments in depth: their lifecycle, FragmentManager, transactions, communication patterns, and building dynamic multi-pane layouts.
What You'll Learn
Android Fragments in depth: their lifecycle, FragmentManager, transactions, communication patterns, and building dynamic multi-pane layouts — Fragments let you build adaptive UIs that work across phones and tablets. They are essential for modern Android apps and the Navigation component.
Why It Matters
Fragments let you build adaptive UIs that work across phones and tablets. They are essential for modern Android apps and the Navigation component.
Real-World Use
A news app uses a master-detail layout: on phones tapping a headline replaces the screen; on tablets the list and article appear side by side using two fragments.
Learning Path
flowchart LR
[Activity Lifecycle] --> [Fragments] --> [Fragment Transactions] --> [Jetpack Navigation]
style 2 fill:#4CAF50,color:#fff
Fragment with ViewBinding
class HeadlineFragment : Fragment() {
private var _binding: FragmentHeadlineBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentHeadlineBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recyclerView.adapter = HeadlineAdapter(headlines)
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
}
override fun onDestroyView() { super.onDestroyView(); _binding = null }
}
Expected output: Fragment inflates its layout, sets up RecyclerView in onViewCreated, and cleans up binding in onDestroyView.
Fragment Transaction
supportFragmentManager.commit {
setReorderingAllowed(true)
replace(R.id.fragment_container, ArticleFragment::class.java, Bundle().apply {
putString("article_id", "123")
})
addToBackStack("article")
}
Expected output: The article fragment replaces the current fragment and is added to the back stack.
Shared ViewModel Communication
class SharedViewModel : ViewModel() {
private val _selectedArticleId = MutableLiveData<String>()
val selectedArticleId: LiveData<String> = _selectedArticleId
fun selectArticle(id: String) { _selectedArticleId.value = id }
}
class HeadlineFragment : Fragment() {
private val viewModel: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.recyclerView.adapter = HeadlineAdapter { articleId ->
viewModel.selectArticle(articleId)
}
}
}
Expected output: HeadlineFragment updates the shared ViewModel when an article is tapped. The observing ArticleFragment receives the update automatically.
Common Errors
- IllegalStateException for commit after state loss - check isStateSaved() or use commitNow()
- Fragment not recreated after Process death - restore dynamic fragments in onCreate with non-null savedInstanceState
- View references in background threads - use viewLifecycleOwner.lifecycleScope for coroutines
- Blank screen after configuration change - ensure fragment has a root ViewGroup and correct container
- Nested fragments not showing - use childFragmentManager, not parentFragmentManager
Practice Questions
What is the key difference between Fragment lifecycle and Activity lifecycle?
Why use viewLifecycleOwner instead of this as LifecycleOwner in a fragment?
How does addToBackStack(null) affect the transaction?
When would you use replace vs add in a fragment transaction?
How do fragments communicate when they share the same activity?
Challenge
Build a color picker app: one fragment lists colors; clicking one shows the selected color in a preview fragment (side by side on tablets, full screen on phones). Use a shared ViewModel.
Real-World Task
Refactor a single-activity news app to use master-detail fragments that adapt to screen size. On portrait phones use NavHostFragment. On landscape tablets show both fragments side by side.
Frequently Asked Questions
{{< faq question="Can a fragment exist without an activity?">}} No. Fragments are always hosted by an activity. They are attached/detached as the activity's lifecycle progresses. {{< /faq >}}
{{< faq question="What happens to fragments when the activity is destroyed?">}} They are destroyed too. They can be recreated via FragmentManager.saveFragmentInstanceState. {{< /faq >}}
{{< faq question="How do I pass arguments to a fragment?">}} Use setArguments() with a Bundle before attachment. Never use a custom constructor for data passing. {{< /faq >}}
Security Tip: When passing sensitive data between fragments (user IDs, auth tokens), use a shared ViewModel scoped to the activity rather than Bundle arguments, since Bundles are serialized to disk during process death.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro