Reusability in Android (Kotlin) — Fragment with View Binding

Manav Tamboli
2 min readApr 1, 2021

Adding view binding to fragments can be a bit tedious, especially when using the Single Activity Architecture.

In the official documentation, the preferred way to apply view binding in your fragment is as follows:

In this article, we will try removing all the boilerplate code needed for adding View Binding in our fragments.

Objective

Create a base fragment class supporting View Binding.

What Changes

On taking a look on the above code, it can be noticed that the only thing changing from fragment to fragment will be the View Binding Class and the binding Inflate Method.

Step 1:

First of all , let’s create a base fragment class — FragmentX , with a binding variable. But, we need to specify a View Binding Class Type for the binding variable, which will keep changing from fragment to fragment. So, to make this reusable, we can take the help of Kotlin Generics.

Step 1

Here, we took a Type Parameter with an Upper bound of class ViewBinding, which is the base class for all the generated view binding classes. Adding an upper bound will force to use only View binding classes and not some other random class.

Step 2:

We use the static inflate method which is available in the generated view binding classes. As the method is generated, we cannot use it in our FragmentX . Because, the only thing we know about our type parameter is that it is inherited from ViewBinding, and there is no inflate method directly available in that class.

The easiest way to fix this, is just to take the inflate method as a constructor parameter.

Step 2

Now, we have both the View Binding Class and Inflate method in the FragmentX. In the next step, let’s complete the implementation.

Step 3:

Let’s add a helper property for the binding variable and implement the Fragment.onDestroyView()

Step 3

Our FragmentX is almost ready to use, but we can still extend this to make our code more tidy.

Step 4:

Usually, when we need some initializations in our binding, we do it right after inflating, that is, in Fragment.onCreateView, as below:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {        _binding = inflateMethod.invoke(inflater, container, false)

// Initializations
binding.var1 = 0
binding.var2 = "abcdefg"
doSomethingElse()
return binding.root
}

To do this in the inherited fragments, you will have to do something like this:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {    val view = super.onCreateView(infater, container, savedInstanceState)

doInitializations()
return view
}

Still, it is some boilerplate code. To fix this, we can add an extension function which can be optionally overriden in the child fragments.

Step 4

Using the T.initialize(), there will be no need to override Fragment.onCreateView to do initializations.

Usage

Usage

Alternatives

Kotlin Lazy Delegates with a lifecycle observer, can also be used to remove some boilerplate code, but still you need to override the methods in the fragment. In my opinion, creating a base fragment class is a better way than creating a lazy delegate.

End Notes

The FragmentX covers the usual implementation of Fragment + View Binding, but you can always modify it to meet your requirements.

--

--