You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView通用适配器实现:手动创建View传入ViewHolder

实现可复用通用RecyclerView ListAdapter(手动传入自定义View)

我最近在做一个可复用的通用适配器,不想用传统的XML填充(inflate)方式创建View,而是打算在RecyclerView.ListAdapter的onCreateViewHolder方法里直接传入预先创建好的自定义View。特意查了官方文档确认这个方案是可行的——官方明确说了:

你可以手动创建新View,也可以从XML布局文件中填充它。

下面是我的适配器实现代码:

class BaseAdapter<T, V : View>(
    private val adapterConfig: AdapterConfig<T, V>
) : ListAdapter<T, BaseViewHolder<V>>(DiffUtilItemCallback<T>()) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<V> {
        // 直接使用预先创建好的自定义View,替代inflate布局的方式
        val customView = adapterConfig.createItemView(parent.context)
        return BaseViewHolder(customView)
    }

    override fun onBindViewHolder(holder: BaseViewHolder<V>, position: Int) {
        adapterConfig.bindItem(holder.itemView, getItem(position), position)
    }

    // 通用ViewHolder,直接持有自定义View实例
    class BaseViewHolder<V : View>(itemView: V) : RecyclerView.ViewHolder(itemView)
}

// 配置接口,封装View创建和数据绑定的业务逻辑
interface AdapterConfig<T, V : View> {
    fun createItemView(context: Context): V
    fun bindItem(itemView: V, item: T, position: Int)
}

// 通用DiffUtil回调,可根据业务需求重写判断逻辑
class DiffUtilItemCallback<T> : DiffUtil.ItemCallback<T>() {
    override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
        // 示例:直接判断对象相等,实际可改为判断唯一ID相等
        return oldItem == newItem
    }

    override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
        return oldItem == newItem
    }
}

这个方案的好处挺明显的:

  • 彻底解耦了View的创建逻辑,适配器只负责列表通用逻辑,不用关心具体View实现
  • 自定义View可以独立开发、单独复用,不用和适配器绑定死
  • 省去了重复的布局inflation代码,灵活性拉满

使用的时候只需要实现AdapterConfig接口,传入你的自定义View创建逻辑和数据绑定逻辑就行,非常省心。

内容的提问来源于stack exchange,提问作者user3448282

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:59:03