RecyclerView+Databinding best practice

📢 Hello Hello, here is the code on the summer rain, a android beginners, will also bring their own learning experience regularly 📢 🤔 the android framework for all components of the data binding library, if you are interested you can also view the official document data binding library 🤔 😍 it before it’s we can start 😍 now

Add DataBinding support

To configure your application to use dataBinding, add the dataBinding element to the build.gradle file of your application module, as shown in the following example:

 / / open dataBinding
dataBinding {
    enabled = true
}
Copy the code

Data preparation

For RecyclerView, the first thing we need to prepare is data, so we need to make RecyclerView adapt text and picture display at the same time, let’s take a look at the definition of model

😎 For images, we just need to include a drawable attribute

class Image(var drawable: Drawable):BindingAdapterItem {
    override fun getViewType(a): Int {
        return R.layout.image_item
    }
}
Copy the code

😀 For text, just make it contain a text attribute

class Text(val text: String):BindingAdapterItem {
    override fun getViewType(a): Int {
        return R.layout.text_item
    }
}
Copy the code

Use the data binding library

Layout and binding expressions

With the expression language, you can write expressions that associate variables with views in a layout. The data binding library automatically generates the classes needed to bind the views in the layout to your data objects. The library provides import, variable, and include functionality that you can use in your layout.

These functions of the library coexist seamlessly with your existing layout. For example, binding variables that can be used in expressions are defined within the data element, the sibling of the root element of the interface layout. Both elements are wrapped in the Layout tag, as shown in the following example:


      
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="item"
            type="com.gcode.databindingsample.model.Text" />
    </data>
    <ConstraintLayout... /> <! -- UI layout's root element -->
</layout>
Copy the code

View with ID

The data binding library creates immutable fields in the binding class for each view with an ID in the layout. For example, if we create a Text object, we have declared its name and corresponding type type in data. The data binding library will create a Text field of type TextView based on the following layout:


      
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="item"
            type="com.gcode.databindingsample.model.Text" />
    </data>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{item.text}"
        android:gravity="center"
        android:textSize="25sp"/>
</layout>
Copy the code

Preparation of adapters

😗 Let’s take a look at the complete adapter code first

class BindingAdapter(var items: MutableList<BindingAdapterItem>) : RecyclerView.Adapter<BindingAdapter.BindingHolder>() {

    / * * *@returnThe view */ of the Adapter is returned
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder {
        val binding = DataBindingUtil.inflate<ViewDataBinding>(
            LayoutInflater.from(parent.context),
            viewType,
            parent,
            false
        )
        return BindingHolder(binding)
    }
    
    /** * data binding */
    override fun onBindViewHolder(holder: BindingHolder, position: Int) {
        holder.bindData(items[position])
    }

    override fun getItemCount(a) = items.size

    override fun getItemViewType(position: Int) = items[position].getViewType()

    class BindingHolder(var binding: ViewDataBinding) : ViewHolder(binding.root) {
        fun bindData(item: BindingAdapterItem?). {
            binding.setVariable(BR.item, item)
        }
    }
}
Copy the code

🤔 First we use the viewType when using databindingutil.inflate (), which is created in the fun getItemViewType(position: Int, so we can declare an interface and have our model implement that interface

interface BindingAdapterItem {
    fun getViewType(a): Int
}
Copy the code

😚, where we can also see that getViewType() returns the layout ID corresponding to item

class Image(var drawable: Drawable) : BindingAdapterItem {
    override fun getViewType(a): Int {
        return R.layout.image_item // the layout id used by the Image object}}Copy the code

😲 then override the getItemViewType method in the Adapter to get the viewTypes for different items

override fun getItemViewType(position: Int) = items[position].getViewType()
Copy the code

😄 Also, sometimes the system does not know about specific binding classes. For example, a RecyclerView.Adapter that runs for arbitrary layouts does not know about specific binding classes. The binding value must still be specified when the onBindViewHolder() method is called. We need to use the setVariable method here

binding.setVariable(BR.item, item)
Copy the code

Note: The data binding library generates a class called BR in the module package that contains the ID of the resource used for the data binding. In the example above, the library automatically generates the br.item variable.

😎 That’s it for now, let’s get the data ready and see what happens

Code section

Writing code is not easy, if you find my project helps you, welcome star Fork, your support is my motivation to write code!

Complete code reference AndroidHappyClub/DataBindingBasic, at the same time, according to this design thought I designed is suitable for general VastAdapter RecyclerView, click to view the details, For an introduction to The VastAdapter, see the Universal RecyclerView Adapter