在 RecyclerAdapter 中使用 DataBinding 的优势

Advantage of using DataBinding in RecyclerAdapter

我是 Kotlin 和 DataBinding 的新手,基于 Google I/O Android App on Github 我编写了一个可用的适配器,但我无法完全理解为什么有人会更喜欢 DataBinding 而不是传统方法?在这种情况下有优势吗?:

 internal class RecyclerAdapterKt : RecyclerView.Adapter<BaseViewHolder>() {

    private val data = ArrayList<Item>()

    ...

    /* with data binding */
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return BaseViewHolder.BasicItemViewHolder(ItemViewBinding.inflate(inflater, parent, false))
    }

    override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
        val item = data[position]
        (holder as BaseViewHolder.BasicItemViewHolder).bind(item)
    }

    // without data binding
    //    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
    //        val view = from(parent.context).inflate(R.layout.item_view, parent, false)
    //        return BaseViewHolder(view)
    //    }
    //
    //    override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
    //        val item = data[position]
    //        holder.tv_title.text = item.title
    //        holder.tv_message.text = item.message
    //    }

    ...

  sealed class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    class BasicItemViewHolder(
        val binding: ItemViewBinding
    ) : BaseViewHolder(binding.root) {

        fun bind(item : Item) {
            binding.tvTitle.text = item.title
            // Difference with using itemView.tv_title.text?
            binding.tvMessage.text = item.message            
        }
    }
  }

为什么不通过 itemView 直接访问 fun bind() 中的布局视图?

实际上,它会减少 ViewHolder 绑定函数中的大量样板代码。诀窍在于 Viewholder

的 XML 和 bind 函数

数据绑定到位后,您的 ViewHolder class 将跟随

class BaseViewHolder(private val itemViewBinding: ItemViewBinding): RecyclerView.ViewHolder(itemViewBinding.root) {
    fun bind(item: Item) {
         itemViewBinding.item = item
         itemViewBinding.executePendingBindings()
    }
}

假设在数据绑定之前,您XML文件item_view.xml如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width ="match_parent"
        android:layout_height="match_parent">
        <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/tvTitle"/>
        <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/tvMessage/>
</LinearLayout>

数据绑定后,您的XML文件item_view.xml将如下

<layout>
    <data>
       <variable name="item"
                 type="com.sample.Item"/>
       <!--your Item model should be defined in the packagename com.sample-->
    </data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width ="match_parent"
        android:layout_height="match_parent">
        <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/tvTitle"
          android:text="@{item.title}"/>
        <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/tvMessage"
          android:text="@{item.message}"/>
</LinearLayout>

因此,无论我们在 Item 模型中添加多少属性,绑定函数都是相同的 class。所以优点是减少样板代码