Android Hilt Fragment — Complete Guide
In this tutorial, you'll learn about Android Hilt Fragment. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
The Problem
Your Fragment's injected fields are null, or you share a ViewModel between parent and child fragments but get different instances.
Wrong Approach ❌
// Missing @AndroidEntryPoint
class MyFragment : Fragment() {
@Inject lateinit var repo: UserRepository // Always null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
repo.loadUsers() // NPE!
}
}
// Incorrect ViewModel scoping
class ParentFragment : Fragment() {
private val vm: SharedViewModel by viewModels()
}
class ChildFragment : Fragment() {
// Gets its OWN instance, not parent's
private val vm: SharedViewModel by viewModels()
}
Output: Null injection. Separate ViewModel instances when sharing should occur.
Right Approach ✅
@AndroidEntryPoint
class MyFragment : Fragment() {
@Inject lateinit var repo: UserRepository
@Inject lateinit var analytics: AnalyticsService
// ViewModel scoped to this fragment
private val vm: UserViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Hilt has already injected fields
repo.loadUsers()
analytics.logScreenView("MyFragment")
}
}
// Shared ViewModel with parent fragment
@AndroidEntryPoint
class ChildFragment : Fragment() {
// Gets the parent fragment's ViewModel
private val vm: SharedViewModel by viewModels(
ownerProducer = { requireParentFragment() }
)
}
// Or scoped to Activity
@AndroidEntryPoint
class MyFragment : Fragment() {
private val vm: SharedViewModel by activityViewModels()
}
Output: Injected dependencies available immediately. Proper ViewModel scoping.
Prevention
- Always annotate Fragments with
@AndroidEntryPoint. - Use
by viewModels(ownerProducer = { requireParentFragment() })for parent-scoped VM. - Use
by activityViewModels()for Activity-scoped VM. - Access injected fields after
super.onViewCreated().
Common Mistakes with hilt fragment
- Mixing let bindings with <- bindings in do notation, producing type errors
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro