This content originally appeared on DEV Community and was authored by Enya Emmanuel
Hey guys! This is my first article on dev.to, and I am super excited about writing again after a long while. Quickly, let's get into the subject at hand.
Building native android apps requires you have a fair knowledge of object oriented programming. This forms the basis for this article because we will leverage on the concepts of Inheritance to set up a base class. In addition to this, you’ll learn about generics, with practical examples.
One may be curious as to why we would want to add another layer of inheritance to our fragment class? This question is usually common with beginner programmers yet to realize the benefits of inheritance.
What is Inheritance in Object Oriented Programming (OOP)?
Inheritance is a feature in-which a class inherits all the features of another class. The class from which the features are inherited is known as the base class, super class or parent class and the class that inherits the features is known as derived class, subclass or child class.
E.g. If Class D extends A, it is inheriting the features of A.
What are Generics?
Generics are simply parameterized types. The idea is to allow type (Integer, String, … etc, and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.
Enough theory, let's get started on creating a base fragment class.
STEP 1:
Create a class BaseFragment that extends a Fragment
abstract class BaseFragment<VBinding : ViewBinding, ViewModel : BaseViewModel> : Fragment() {
open var useSharedViewModel: Boolean = false
protected lateinit var viewModel: ViewModel
protected abstract fun getViewModelClass(): Class<ViewModel>
protected lateinit var binding: VBinding
protected abstract fun getViewBinding(): VBinding
private val disposableContainer = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
init()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpViews()
observeData()
}
open fun setUpViews() {}
open fun observeView() {}
open fun observeData() {}
private fun init() {
binding = getViewBinding()
viewModel = if (useSharedViewModel) {
ViewModelProvider(requireActivity()).get(
getViewModelClass()
)
} else {
ViewModelProvider(this).get(getViewModelClass())
}
}
fun Disposable.addToContainer() = disposableContainer.add(this)
override fun onDestroyView() {
disposableContainer.clear()
super.onDestroyView()
}
}
abstract class BaseFragment<VBinding : ViewBinding, ViewModel : BaseViewModel> : Fragment()
Basically what we've done here is create a BaseFragment
which accepts two types, that is a ViewBinding and a ViewModel. With this class, we move common logic and set up to one place, thereby reducing duplicate codes (biolerplates).
The viewModel class and the ViewBinding object specified as fields in the base class will be provided by the subclass when getViewModelClass()
and getViewBinding()
are invoked, respectively.
open fun setUpViews() {}
and open fun observeData() {}
are methods with a default empty implementation. This makes it optional for its sub classes to override. The sub classes are not forced to override these methods.
STEP 2:
With the base class set up, we'll use it by creating another fragment class that extends BaseFragment.
@AndroidEntryPoint
class UserListFragment : BaseFragment<FragmentUserListBinding, UserViewModel>() {
override var useSharedViewModel = true
override fun getViewModelClass() = UserViewModel::class.java
override fun getViewBinding() = FragmentUserListBinding.inflate(layoutInflater)
override fun setUpViews() {
// set up recycler view and bind data to UI
}
}
From the code block above, we have been able to achieve a simple and readable fragment class, using the concepts of inheritance and generics.
In summary,
- Using a base fragment helps you avoid code and pattern repetition.
- You achieve a clean and readable code with the concepts discussed in this article.
That is it for this article. Please share your thoughts on this subject.
This content originally appeared on DEV Community and was authored by Enya Emmanuel
Enya Emmanuel | Sciencx (2021-04-07T07:32:54+00:00) How to set up a Base Fragment Class with ViewBinding and ViewModel on Android. Retrieved from https://www.scien.cx/2021/04/07/how-to-set-up-a-base-fragment-class-with-viewbinding-and-viewmodel-on-android/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.