【Android】分享一个在RecyclerView中使用数据绑定(DataBinding)的Adapter基类

BaseDataBindingAdapter是一个简易的、在RecyclerView中使用数据绑定、只支持一种数据类型和布局的Recycler Adapter基类,适用于单一数据、布局类型的简单RecyclerView。

使用BaseDataBindingAdapter,实现一个简易的、使用数据绑定的Recycler Adapter,只需要极少量的代码。BaseDataBindingAdapter的实现非常简单,这在其使用便捷的同时,也导致了不适用于多布局类型的RecyclerView。

一、BaseDataBindingAdapter代码

/**
 * 加入了DataBinding的RecyclerView.Adapter基类,在RecyclerView中实现了DataBinding,适合简单列表。
 * 只支持绑定一种数据类型,重写[layoutId]设置布局,重写[onBindViewHolder]抽象函数实现数据绑定。
 *
 * 其中[T]是数据类型,在xml中使用;[B]是对应布局的数据绑定类。
 *
 * 实现类只需要重写布局id[layoutId]和[onBindViewHolder]一个抽象函数即可。
 */
abstract class BaseDataBindingAdapter<T, B : ViewDataBinding> 
	: RecyclerView.Adapter<BaseDataBindingAdapter.ViewHolder>() {
    protected val TAG = javaClass.simpleName // TAG

    /**
     * 数据列表,只支持一种类型的数据
     */
    protected val data = mutableListOf<T>()
    override fun getItemCount(): Int = data.size

    /**
     * 布局文件的id,在子类中实现(可以在构造函数中重写)
     */
    abstract val layoutId: Int

    /**
     * ViewHolder,因为实现数据绑定,所以实际操作由[binding]实现。
     */
    open class ViewHolder(open val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root)

    final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val binding = DataBindingUtil.inflate<B>(
            LayoutInflater.from(parent.context), layoutId, parent, false
        )
        return ViewHolder(binding)
    }

    /**
     * 全量更新数据
     */
    fun setData(_data: List<T>?) {
        Log.v(TAG, "setData: $_data")
        data.clear()
        if (!_data.isNullOrEmpty()) data.addAll(_data)
        notifyDataSetChanged()
    }

    final override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        @Suppress("UNCHECKED_CAST")
        onBindViewHolder(holder.binding as B, data[position])
        holder.binding.executePendingBindings()
    }

    /**
     * 显示数据时使用。通过[binding]设置布局中对应的变量[item]更新数据。
     */
    abstract fun onBindViewHolder(binding: B, item: T)

}

二、示例

实现效果:

一个简单的用户列表。

实现效果

示例代码

为了避免示例复杂化,这里只在Recycler item中使用了数据绑定作为演示。

1. 布局

Activity布局

<?xml version="1.0" encoding="utf-8"?>
<merge 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">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#eeeeee"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</merge>

Recycler item布局

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tool="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="user"
            type="top.littlefogcat.ui.databindinginrecyclerview.User" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:padding="16dp">

        <ImageView
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_marginEnd="10dp"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text='@{"姓名:"+user.name+",年龄:"+user.age}'
            tool:text="姓名:小波,年龄:18" />
    </LinearLayout>
</layout>

2. 类代码

DatabindingRecyActivity

class DatabindingRecyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_databinding_recy)

        val adapter = UserListAdapter(R.layout.user_item)
        rv.adapter = adapter

        // -------------------------- 加载假数据 -----------------------------
        arrayOf(
            "Alice", "Bob", "Clark", "Diana", "Ella", "Frank", "George", 
            "Holy shit", "Iris", "John", "Ketty", "Laura", "Mark",
            "Nash", "Olive", "Peter", "Quincy", "Rita", "Sandra", "Tony", 
            "Uzi", "Vincent", "Worker", "XBox", "Yuri", "Zoey"
        ).map {
            User(it, Random.Default.nextInt(80))
        }.toMutableList().run {
            adapter.setData(also { shuffle() })
        }
        // ------------------------------------------------------------------
    }
}

UserListAdapter

class UserListAdapter(override val layoutId: Int) : BaseDataBindingAdapter<User, UserItemBinding>() {
    override fun onBindViewHolder(binding: UserItemBinding, item: User) {
        binding.user = item
    }
}

可以看到,只需要一行代码就可以实现一个数据绑定的Recycler Adapter,对于单一少量数据类型的RecyclerView非常好用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android数据绑定一个支持双向绑定的库,它可以帮助你将UI组件和数据模型绑定起来,从而可以轻松地更新UI组件或数据模型的值。 Android RecyclerView是一种用于显示大量数据的高级组件,它可以在滚动时动态地加载和卸载数据项,并提供了类似于ListView的布局管理器。 使用Android数据绑定RecyclerView,可以更轻松地实现列表的数据绑定。你可以在适配器使用数据绑定表达式来更新列表项视图的值,同时还可以监听数据模型的变化,以便在数据更新时刷新列表项。 要在RecyclerView使用数据绑定,需要将适配器继承自RecyclerView.Adapter,并且在绑定视图时使用DataBindingUtil类来获取视图的绑定对象。然后,可以在绑定对象使用数据绑定表达式来更新视图的值。 例如,下面的代码片段演示了如何使用数据绑定更新RecyclerView列表项的文本视图: ```java public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> { private List<MyData> mDataList; // ... @Override public void onBindViewHolder(MyViewHolder holder, int position) { MyData data = mDataList.get(position); ViewDataBinding binding = DataBindingUtil.bind(holder.itemView); binding.setVariable(BR.myData, data); binding.executePendingBindings(); } } public class MyViewHolder extends RecyclerView.ViewHolder { // ... public MyViewHolder(View itemView) { super(itemView); } } ``` 在MyViewHolder类,我们只需要简单地继承自RecyclerView.ViewHolder,并且不需要实现任何逻辑。在适配器的onBindViewHolder()方法,我们首先获取当前位置的数据模型,然后使用DataBindingUtil.bind()方法获取视图的绑定对象。接下来,我们使用setVariable()方法将数据模型设置为绑定对象的属性,然后调用executePendingBindings()方法来立即更新视图。 需要注意的是,在使用数据绑定时,你需要在build.gradle文件添加以下依赖: ```groovy android { // ... dataBinding { enabled = true } } dependencies { // ... implementation 'com.android.databinding:library:1.4.0' } ``` 希望这个回答能够帮助你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值