When writing regular code to access a UI component from the code behind, we usually need to declare and then use findViewById(). However, with View Binding, we can completely eliminate the findViewById step and enjoy several advantages. In this article, I will introduce View Binding and provide some examples of its usage.
Brief introduction to View Binding
View Binding is a component in Android Jetpack that helps eliminate the findViewById step in the coding process by generating corresponding classes for XML files in the project. Here are some benefits it brings:
- Reduces the number of lines of code.
- Eliminates the possibility of passing the wrong ID and causing
NullPointerException. - Automatically generates classes based on XML, ensuring the correct UI elements and types are queried.
- Handles scenarios with different configurations, such as portrait and landscape screens.
View Binding can be considered a lightweight version of Data Binding with the main function of eliminating findViewById. If you want to automatically bind data and UI from XML to code-behind for automatic updates and also eliminate findViewById, Data Binding is more suitable.
Enable View Binding
To enable View Binding in an Android project, follow these steps:
- Open the
build.gradle.appfile. - Inside the
androidblock, add the following code:
1
2
3
buildFeatures {
viewBinding true
}
View Binding in Activity
To use View Binding in an Activity, follow these steps:
- Create a variable of the corresponding View Binding class
1
2
3
4
5
6
7
8
9
10
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//setContentView(R.layout.activity_main)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textHelloWorld.text = "hello from the main activity"
}
}
According to convention, the variable is named binding, and the data type depends on the name of the layout. For example, if we have activity_main.xml, the View Binding class that is automatically generated will be ActivityMainBinding (append "Binding" to the layout name and capitalize the first letter).
Next, we inflate the layout to assign the current layout to the binding variable.
After this step, the binding variable can directly query the corresponding components within the layout. In this case, root is always created to point to the outermost layout, which contains all the other components in the XML file.
It's important to note that when using View Binding, we use setContentView(binding.root) instead of setContentView(R.id.xxxx). Both cannot be used simultaneously.
We can query the remaining components directly based on their IDs. For example, if we have an ID called text_hello_world, we can query it using binding.textHelloWorld. Since kotlin automatically generates the getter/setter functions, we can access it as shown below:
1
2
3
4
5
6
7
8
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
// ...
var currentText = binding.textHelloWorld.text
binding.textHelloWorld.text = "hello from the main activity"
}
}
View Binding and Fragment - Inflate
For Fragments, we have two approaches: inflate and bind. Let's start with inflate.
To use View Binding in a Fragment using the inflate approach, follow these steps:
- Create a Fragment and override the
onCreateViewmethod.
1
2
3
4
5
6
7
8
class InflateFragment : Fragment(R.layout.fragment_inflate) {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_blank, container, false)
}
}
Here, we pass the ID of the corresponding layout, which in this case is R.layout.fragment_inflate.
According to convention, we create two variables: _binding (nullable) and binding. The _binding variable is used for inflating or binding the layout, while the binding variable retrieves the inflated/bound result from _binding for querying. If _binding is null, a NullPointerException is thrown.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class InflateFragment : Fragment(R.layout.fragment_inflate) {
private var _binding: FragmentInflateBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentInflateBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroy() {
_binding = null
super.onDestroy()
}
}
After inflating the layout, we can use the binding variable to query the components as we did in the Activity example. It's important to always override onDestroy and set _binding to null when the Fragment is destroyed.
View Binding and Fragment - Bind
Similar to the previous approach, but this time we bind the view in the onViewCreated method after the view has been created. Here's an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
class BindFragment : Fragment(R.layout.fragment_bind) {
private var _binding: FragmentBindBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentBindBinding.bind(view)
}
override fun onDestroy() {
_binding = null
super.onDestroy()
}
}
Since the steps are similar, I won't explain them again. Just note the difference in the timing of inflating or binding the view, depending on whether the view has been created or not.
Conclusion
About a month ago, I read a book on Android programming for beginners, and I noticed that the View Binding chapter was one of the first chapters. Throughout the book, View Binding was used continuously. From there, I researched and found that it's a useful knowledge for beginners in programming, like myself.
In this article, I highlighted some advantages of View Binding and demonstrated its usage in Activities and Fragments.
References
- Skillshare course - How to use Android View Binding like a pro
- Medium article - Use View Binding to Replace findViewById
- GitHub source code - ViewBinding_Like_a_Pro