Android DataBinding

DataBinding

The improvement of DataBinding vs findViewById() is performance and cleanliness.

For larger apps where we have a lot of views, findViewById is way to slow as it has to search through all layouts every time. This doesn’t happen with DataBinding.

The usage of DataBinding eliminates the need for findViewById().

Implementation

Go to build.gradle file and enable it.

android {
	buildFeatures {
		dataBinding = true
	}
}

Then we need to wrap all layouts where we are going to use it in between <layout></layout> tags and move the declarations into this tags.

<layout xmlns:android="..."
	xmlns:app="..."
	xmlns:tools="...">
	<androidx.constraintlayout.widget.ConstraintLayout>
		...
	</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

We did this for activity_main, when we rebuild an ActivityMainBinding class will be automatically created.

Now we go to our MainActivity class. We added the Binding class and replaced the default setContentView function with the new binding var.

This binding var holds values for all items inside the XML view.

class MainActivity: AppCompatActivity() {

	private lateinit var binding: ActivityMainBinding
	
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
		binding.submitButton.setOnClickListener {
			displayGreeting()
		}
	}
	
}

DataBinding with Objects

We can send objects directly to the view. This reduces the code we have to write in our ViewController classes.

We have the following data class, which we want to send to the view.

data class Student (
	var id:Int, 
	var name:String,
	var email:String
)

Using DataBinding it’s possible to send the whole Student to the view.

To be able to directly use a data class in the layout, first of all we need to add a reference to this class.

  1. Inside activity_main we need to insert a set of data tags at the top level of the layout.
  2. Then we may directly refer to data variables from the view.
<layout xmlns:android="..."
	xmlns:app="..."
	xmlns:tools="...">
	
	<data>
		<variable 
		   name="student"
		   type="es.mcodes.whole.package.data.Student" />
	</data>
	
	<androidx.constraintlayout.widget.ConstraintLayout>
		<TextView
		   ...
		   android:text="@{student.name}"
		   ...  />
		
		<TextView
		   ...
		   android:text="@{student.email}"
		   ...  />
	</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Now we can refer to this student object reference from the view. If we go back to MainActivity, we may directly asign Students to the view.

class MainActivity: AppCompatActivity() {

	private lateinit var binding: ActivityMainBinding
	
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
		// this here
		binding.student = getStudent()
	}
	
	private fun getStudent(): Student {
		return Student(1, "Mario", "mariocodes@gmail.com")
	}
	
}

DataBinding Fragments

When we use DataBinding with Fragments we have to return the root property.
This is an example of how it works.

class HomeFragment: Fragment() {
	private lateinit var binding: FragmentHomeBinding
	
	override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
		savedInstanceState: Bundle?): View? {
		// inflate the layout for this fragment
		binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
		return binding.root
	}
}