In this post i would show you how to use View binding in Activities and Fragments.
As an Android software developer, am sure you are very familiar with findViewById and how tedious it is to track what id belonged to what Widget in what layout file, not to mention the amount of boilerplate it can cause if you have a lot of views for a particular layout file.
View binding is a feature that allows you to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module. An instance of a binding class contains direct references to all views that have an ID in the corresponding layout.
Google documentation
According to that quote from Google docs for every xml layout there is generated binding class, all you just need to do is instantiate that class and every view with an Id would be available for use. Alright much talk lets start coding.
The very first thing you need to do is enabling view binding in your project, go to your app level build.gradle file - this is the file where you add dependencies for your project; and add the following below
android {
...
buildFeatures {
viewBinding true
}
}
Now sync the project, after sync is successful move to your MainActivity.kt class let us instantiate the binding class
class MainActivity : AppCompatActivity {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
The code snippet above is doing three things
We declared the variable named binding as a lateinit which means we would initialize it later, and this variable is of type ActivityMainBinding which is the generated binding class of activity_main layout.
Now in the onCreate method the variable binding is initialized by setting it equal to ActivityMainBinding then call the inflate method of this class and also passing the parameter layoutInflater.
The final step is to remove the R.layout.activity_main from setContentView() and instead pass binding.root as the parameter.
Now with just this setup we can access any View with an id in activity_main layout file without calling findViewById, let us test what we have done so far.
For testing this out add a button to your layout file and give it an id, my button's id would be clickBtn.
In the MainActivity.kt class we can reference that button by simply calling binding.clickBtn
....
....
binding.clickBtn.setOnClickListener(->
Toast.makeText(this, "Button Clicked", Toast.LENGHT_SHORT).show()
)
}
}
And there you have it clean and simple less boilerplate, now let me show you how to instantiate the binding class inside a fragment.
class TestFragment : Fragment() {
private lateinit var binding: TestFragmentBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = TestFragmentBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
}
The key difference between Activity and Fragment is the onDestroyView() where we set binding = null because fragments outlive their views so every reference to the binding class has to be cleared.
If you do not want a binding class to be generated for a layout file all you have to do is add the following to that file
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
I hope this little write up has helped you clarify how View binding works generally, if you have ever built an App with a lot of Views then you would have noticed how tiring having to write findViewById everytime a view is added to our layout can be.
View Binding should not be confused for Data binding - which is also a way of binding views but it works in a completely different way to View binding. Thanks for reading.
Top comments (0)