View Binding in android

Aayush Puranik
5 min readJun 26, 2020

View binding 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, eg. if layout name for MainActivity.kt is activity_main.xml so the view binding file generated for main activity will be ActivityMainBinding.

To enable view binding in project add this line in build.gradle file in android{} section

viewBinding {
enabled = true
}

Since for all the layout Binding files will be created, there is an option to ignore a layout file while generating a binding class. You can do this with the help of tools:viewBindingIgnore="true"add this line in parent tag of layout file. After this the Binding classes will not be created for that particular view layout and then we can use findViewById.

Every binding class includes a root property, this root property represents the view and provide direct reference to the root view objects such as button, textViews, editText, etc. of corresponding layout file.

here is an example of view binding in Activity

class MainActivity : AppCompatActivity() {

private lateinit var viewBinding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

viewBinding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root

setContentView(view)

// setting data after binding
viewBinding.dataTV.text = "View Binding"
viewBinding.clickActionBtn.setOnClickListener {
binding.activityParentLayout.visibility = View.GONE
supportFragmentManager.beginTransaction()
.replace(R.id.parentLayout, VBFragment())
.addToBackStack("nav")
.commit()
}
}
}

and below is an example of view binding in fragment

class VBFragment : Fragment() {

private var _viewBinding: FragmentVBBinding? = null
private val viewBinding get() = _viewBinding!!
private var status: Boolean = true

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_viewBinding = FragmentVBBinding.inflate(inflater, container , false)

val view = binding.root
// Inflate the layout for this fragment

viewBinding.clickActionBtn.setOnClickListener {
val text = if(status) "Button Clicked" else ""
binding.dataTV.text = text

status = !status
}

return view
}

override fun onDestroyView() {
_viewBinding = null
super.onDestroyView()
}
}

Note: Fragments outlive their views. Make sure you clean up any references to the binding class instance in the fragment’s onDestroyView() method.

If a view layout contains a view that is assigned an id as :
android:id="@+id/my_task_recycler_view"
// the property generated in binding class would remove underscores // and it will be available as
viewBinding.myTaskRecyclerView.layoutManager = LinearLayoutManager(context)

On each binding class, view binding exposes three public static functions to create a binding an object:
1.) inflate(inflater) : Use this in an activity onCreate where there is no parent view to pass to the binding object.
2.) inflate(inflater, parent, attachToParent) : Use this in a fragment or a RecyclerView Adapter or ViewHolder where you need to pass the ViewGroup of binding object.
3.) bind(rootView) : Use this when you have already inflated the view and you just want to use the view binding to avoid findViewById. This is useful for fitting view binding into your existing infrastructure and when refactoring code to use ViewBinding. We can use bind method in Recycler view adapter in onBindViewHolder where view is already created and we just need to pass the view into bind method as parameter bind(holder.itemView) class

In the case of included layouts, view binding will create a reference to the included layout’s binding object. Note that the <include> tag has an id: android:id="@+id/includes". If we want to implement view binding in bottom sheet we can assign id for that bottom sheet and implement changes we can do the same with merge layout.

<include android:id="@+id/includes" layout="@layout/titlebar" />
then for using view binding here
viewBinding.includes.titleTextView = "This is view binding example."

If we want to implement view binding in recycler view then we need to do following changes to recycler view adapter

class RVAdapter(private val list: ArrayList<UserModel>) : RecyclerView.Adapter<RVAdapter.RVViewHolder>() {

class RVViewHolder(binding: RvRowViewBinding) : RecyclerView.ViewHolder(binding.root)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVViewHolder {
return RVViewHolder(
RvRowViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}

override fun onBindViewHolder(holder: RVViewHolder, position: Int) {
RvRowViewBinding.bind(holder.itemView).apply {
nameTextView.text = list[position].name
designationTextView.text = list[position].designation
}
}

override fun getItemCount() = list.count()
}
// this is row view
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="10dp">

<TextView
android:id="@+id/nameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/designationTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"/>
</LinearLayout>

Benefits of using ViewBinding:
findViewById is the source of many user-facing bugs in android. It is easy to pass an id that is not in the current layout producing null and a crash and view binding helps in avoiding these issues.

1.) Null Safe : In findViewById there is a risk of taking a reference for a view that might be invalid but view binding has a direct reference of view objects of the layout there is no risk of referencing an invalid view object

2.) Type Safe : The fields in each binding class have types matching the views they reference in the XML file. This means that there’s no risk of a class cast exception.

Disadvantages of using ViewBinding :
1.) View binding does not support two way binding

Difference between data binding and view binding :
1.) Faster compilation in view binding as compared to data binding
2.) Ease of use: View binding does not require specially-tagged XML layout files, so it is faster to adopt in your apps. Once you enable view binding in a module, it applies to all of that module’s layouts automatically.

View binding is created in addition to data binding as a light weight replacement of findViewById without the rest of the data binding library.

View binding is only a replacement for findViewById. If you want to automatically bind views in xml you can use the data binding library. Both libraries can be applied to the same module and they’ll work together.

When both are enabled, layout that uses a <layout> tag will use data binding to generate binding objects. All other layouts will use view binding to generate binding objects.

Because of these considerations, it is best in some cases to use both view binding and data binding in a project. You can use data binding in layouts that require advanced features and use view binding in layouts that do not.

Here is a reference of view binding sample
https://github.com/dev-aayushpuranik/ViewBindingSample
Output :

--

--