Advanced Data Binding in Android: Layout Expressions
Learn how to use layout expressions for data binding in Android and make your code more concise and less error-prone. By Ivan Kušt.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Advanced Data Binding in Android: Layout Expressions
10 mins
- Getting Started
- Recapping Data Binding
- Seeing The Difference to View Binding
- Understanding Layout Expressions
- Using Mathematical and String Operators
- Using String Resources With Parameters
- Handling Events from Views
- Understanding Method References vs. Listener Bindings
- Handling Click Event Using Method Reference
- Handling Events Via Listener Bindings
- Where to Go From Here?
Handling Events from Views
Data binding allows you to handle view events too. You can link an event from view — like click to functions — using layout expressions.
There are two approaches:
- Method references: binding methods with matching signatures to view events.
- Listener bindings: lambda expressions that are evaluated when event is triggered.
Understanding Method References vs. Listener Bindings
The major difference between the two is method references create bindings at compile time, while listener bindings are evaluated at run time when the event is triggered. That means errors will be easier to detect when using method references because they are validated at compile time.
On the other hand, listener bindings provide increased flexibility because you can call any bound method from the lambda expression.
Handling Click Event Using Method Reference
You’ll test method references by creating and adding a method for handling click event on button for adding new items.
First, add a class that will hold the function that will be called on click.
Open GroceryListActivity
and add the following class to it:
class Listeners(private val supportFragmentManager: FragmentManager) {
fun onAddGroceryItemClick(view: View) {
val newFragment = NewItemDialogFragment.newInstance(R.string.add_new_item_dialog_title, null)
newFragment.show(supportFragmentManager, "newItem")
}
}
Add imports for FragmentManager
and View
:
import android.view.View
import androidx.fragment.app.FragmentManager
Note that onAddGroceryItemClick
needs to have one argument of type View
. It needs to match onClick
method signature from View.OnClickListener.
Open activity_grocery_list.xml
and add the following variable in data
tags:
<variable
name="listeners"
type="com.raywenderlich.android.gobuy.view.GroceryListActivity.Listeners" />
This binds the new Listeners
class. Now you can bind the onAddGroceryItemClick
from Listeners
. Find Button
with id add_item_button
and add the following property to it:
android:onClick="@{listeners::onAddGroceryItemClick}"
This will wrap onAddGroceryItemClick
in View.OnClickListener
and set it on add_item_button
.
Finally, bind the Listeners
class in GroceryListActivity
by adding the following to the end of onCreate
:
binding.listeners = Listeners(supportFragmentManager)
Remove the code that sets the listener on addItemButton
:
binding.addItemButton.setOnClickListener {
addGroceryItem()
}
Your onCreate
now looks like this:
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(GroceryListViewModel::class.java)
binding = DataBindingUtil.setContentView(this, R.layout.activity_grocery_list)
binding.rvGroceryList.layoutManager = LinearLayoutManager(this)
binding.rvGroceryList.adapter = GroceryAdapter(viewModel.groceryListItems, this, ::editGroceryItem, ::deleteGroceryItem)
binding.total = viewModel.getTotal()
binding.listeners = Listeners(supportFragmentManager)
}
Build and run the app and tap add button.
You’ll see the dialog for adding an item.
Handling Events Via Listener Bindings
You’ll test listener bindings by adding listeners for item edit and delete button clicks. Open grocery_list_item.xml
.
Add the following bindings in the data
tags:
<variable
name="position"
type="Integer" />
<variable
name="adapter"
type="com.raywenderlich.android.gobuy.view.GroceryAdapter" />
This binds GroceryAdapter
with listeners for edit and delete actions: itemEditListener
and itemDeleteListener
. Also, this binds the position
that represents the position of the item being shown in the list. It will be passed to listeners from GroceryAdapter
.
Find Button
with id button_edit
and add the listener binding for onClick
event:
android:onClick="@{() -> adapter.itemEditListener.invoke(position)}"
The lambda expression invokes itemEditListener
and passes the position of the item.
Find Button
with id button_delete
and add the listener binding for onClick
event:
android:onClick="@{() -> adapter.itemDeleteListener.invoke(position)}"
Finally, open GroceryAdapter
and add the following line to onCreateViewHolder
:
binding.adapter = this
This assigns the adapter instance so its listeners can be called in onClick
methods.
Build and run the app and add a few items. Try to delete one. What’s going on?
The app crashes after you tap edit or delete buttons for items. That’s because you didn’t bind the position of the item. This is one of the drawbacks because listener bindings are validated at runtime.
Add the following line in bind
function of ViewHolder
:
binding.position = adapterPosition
This assigns position of the item that was bound to the view.
Build and run the app.
You can again edit and remove items from the list.
That’s it! You’ve mastered layout expressions. Use them wisely!
Where to Go From Here?
You can download the completed project files by clicking on the Download Materials button at the top or bottom of the tutorial.
Check out Data Binding tutorial if you haven’t. If you want to know more about Layout expression take look at the official documentation.
We hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!