-
Notifications
You must be signed in to change notification settings - Fork 8
Additional tips for Data binding
-
Antonio will inject some view holder dependencies data as follow automatically.
- LifecycleOwner to BR.lifecycleOwner
- ViewHolder.itemView to BR.itemView
- ViewHolder.absoluteAdapterPosition to BR.absoluteAdapterPosition
- ViewHolder.bindingAdapterPosition to BR.bindingAdapterPosition
- ViewHolder.layoutPosition to BR.layoutPosition
- Position in onBindViewHolder to BR.itemPosition
-
You just declare the variables and use them in your view holder xml!
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
>
<data>
<variable
name="lifecycleOwner"
type="androidx.lifecycle.LifecycleOwner"
/>
<variable
name="itemView"
type="android.view.View"
/>
<variable
name="absoluteAdapterPosition"
type="Integer"
/>
<variable
name="bindingAdapterPosition"
type="Integer"
/>
<variable
name="layoutPosition"
type="Integer"
/>
<variable
name="itemPosition"
type="Integer"
/>
</data>
<ConstraintLayout>
...
<layout>
Sometimes you want to inject some common data for view holder.
This kind of data cannot be in AntonioBindingModel because it will be bound to a view holder XML at every "onBindViewHolder" moments.
For this situation, You can put additionalVariables
in AntonioAdapter with BR variables.
private fun initAdapter(){
// You also can specify the type of Antonio model for the adapter, if you don't need various view types.
// e.g., AntonioAdapter<ContentSmallModel>()
binding.recyclerView.adapter =
AntonioAdapter<AntonioModel>().apply {
currentList = viewModel.antonioModels
additionalVariables = mapOf(BR.someVariableName to someVariableData, BR.someVariableName2 to someVariableData2)
}
// Don't forget to set the layout manager to your recycler view :)
binding.recyclerView.layoutManager = GridLayoutManager(context,4)
viewModel.onDataSetChanged.observe(this) {
binding.recyclerView.adapter?.notifyDataSetChanged()
}
}
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
>
<data>
<variable
name="someVariableName"
type="io.github.naverz.antonio.sample.antonio.SomeVariableName"
/>
<variable
name="someVariableName2"
type="io.github.naverz.antonio.sample.antonio.SomeVariableName2"
/>
</data>
...
</layout>
LifecycleOwner, which is nearest from the view, will be automatically injected on All of XML inflated from AutoBindingModel
in order to use LiveData for the one or two-way binding.
Doing some changes to your binding does not mean that it will have an immediate effect on your View. Changing things in binding means that it'll be scheduled those changes to be applied in the nearest future.
But In some cases, You need to apply changes immediately. Then you can implement requireExecutePendingBindings
method to return true on your AntonioBindingModel.
e.g,)
data class ContentSmallModel(
val id: String,
@DrawableRes val iconRes: Int,
val price: Int,
val onClick: (id: String) -> Unit,
val onLongClick: (id: String) -> Boolean,
val selectedIds: LiveData<Set<String>>
) : AntonioBindingModel {
override fun layoutId(): Int = R.layout.view_holder_content_small
override fun bindingVariableId(): Int = BR.model
// Implementation
override fun requireExecutePendingBindings() = true
}
[Caution] It might not be as smooth as without this call, So You'd better implement this method when you really need it.