Skip to content

BaseMultiItemAdapter

mumu edited this page Aug 26, 2022 · 1 revision

BaseMultiItemAdapter

继承自BaseQuickAdapter

此类型用于实现简单的多类型布局

因为Jetpack 内部的 ConcatAdapter 本身就是Adapter的集合,起到了代码隔离的作用,不仅如此,还能更简便的刷新内部各个子Adapter。所以,现在v4不再提供各种复杂的多类型Adapter,不仅会给使用者造成困扰,给维护也带来了更多难度。现在ConcatAdapter + 此BaseMultiItemAdapter 已可以实现各种复杂Adapter样式。

基本使用

  • 方法一 先用addItemType()添加Item类型,再调用onItemViewType()确定数据对应的ItemViewType
class TestAdapter(data: List<HomeEntity>) : BaseMultiItemAdapter<HomeEntity>(data) {

    // 类型 1 的 viewholder
    class ItemVH(val viewBinding: HomeItemViewBinding) : RecyclerView.ViewHolder(viewBinding.root)

    // 类型 2 的 viewholder
    class HeaderVH(val viewBinding: DefSectionHeadBinding) : RecyclerView.ViewHolder(viewBinding.root)

    // 在 init 初始化的时候,添加多类型
    init {
        addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener<HomeEntity, ItemVH> { // 类型 1
            override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH {
                // 创建 viewholder
                val viewBinding = HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false)
                return ItemVH(viewBinding)
            }

            override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) {
                // 绑定 item 数据
            }
        }).addItemType(SECTION_TYPE, object : OnMultiItemAdapterListener<HomeEntity, HeaderVH> { // 类型 2
            override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): HeaderVH {
                // 创建 viewholder
                val viewBinding = DefSectionHeadBinding.inflate(LayoutInflater.from(context), parent, false)
                return HeaderVH(viewBinding)
            }

            override fun onBind(holder: HeaderVH, position: Int, item: HomeEntity?) {
                // 绑定 item 数据
            }

            override fun isFullSpanItem(itemType: Int): Boolean {
                // 使用GridLayoutManager时,此类型的 item 是否是满跨度
                return true;
            }

        }).onItemViewType { position, list -> // 根据数据,返回对应的 ItemViewType
            if (list[position].isSection) {
                SECTION_TYPE
            } else {
                ITEM_TYPE
            }
        }
    }

    companion object {
        private const val ITEM_TYPE = 0
        private const val SECTION_TYPE = 1
    }
}
  • 方法二 Adapter 类中不写,在外部注册。原理一致.
adapter.addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener<HomeEntity, ItemVH> { // 类型 1
    override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH {
        // 创建 viewholder
        val viewBinding = HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false)
        return ItemVH(viewBinding)
    }

    override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) {
        // 绑定 item 数据
    }
}).onItemViewType { position, list -> // 根据数据,返回对应的 ItemViewType
    if (list[position].isSection) {
        SECTION_TYPE
    } else {
        ITEM_TYPE
    }
}

Section布局

同【基本使用】一致。这里只强调一点,需要满跨度的,需要重写isFullSpanItem方法。

adapter.addItemType(SECTION_TYPE, object : OnMultiItemAdapterListener<HomeEntity, HeaderVH> {
    
    ...

    override fun isFullSpanItem(itemType: Int): Boolean {
        // 使用GridLayoutManager时,此类型的 item 是否是满跨度
        return true;
    }
}