ConcatAdapter

ConcatAdapter

多个adapter 根据一定的顺序拼接

MutiType 类型实现

实现方案

  • 第三方库 com.chad.library.adapter[http://www.recyclerview.org/]
  • ConcatAdapter
  • List<T> 包含itemType,在RecyclerView.Adapter 中重写getItemViewType 实现

已实现此功能实现对比

List<T> MultiItemEntity/Header&FooterView ConcatAdapter
实现难易程度
代码量 紧簇 紧簇阅读性高 相对冗余
跨平台
可扩展性

跨平台类似 kmm 不同类型终端数据在非平台相关处维护。

ConcatAdapter 实现

导入

implementation("androidx.recyclerview:recyclerview:1.2.1")

初始化

val config = ConcatAdapter.Config.Builder().setIsolateViewTypes(false).build()
val concatAdapter = ConcatAdapter(config, imageAdapter2, titleAdapter2, specAdapter2, featureAdapter2)
    // 設定 recyclerview
    binding.productRecyclerview.apply {
        layoutManager = LinearLayoutManager(
            this@ProductActivity,
            LinearLayoutManager.VERTICAL,
            false
        )
        // isNestedScrollingEnabled = false
        adapter = concatAdapter
    }

参考

https://github.com/foxtsai2333/ConcatAdapterDemo.git

优化

优化 Adapter

import android.annotation.SuppressLint
import android.content.Context
import android.view.*
import androidx.annotation.LayoutRes
import androidx.core.view.ViewCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView

abstract class BindableViewHolder2<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
    abstract fun bind(item: T)
}

fun <T> List<T>.adapt(
    context: Context,
    @LayoutRes itemId: Int,
    bindCall: View.(T) -> Unit
) = object : RecyclerView.Adapter<BindableViewHolder2<T>>() {
    // Inflates the item views
    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): BindableViewHolder2<T> {
        val itemView = LayoutInflater.from(context).inflate(itemId, parent, false)
        return object : BindableViewHolder2<T>(itemView) {
            override fun bind(item: T) = itemView.bindCall(item)
        }
    }

    override fun getItemCount(): Int = size

    override fun onBindViewHolder(holder: BindableViewHolder2<T>, position: Int) =
        holder.bind(get(position))

}

open class ConcatBindableAdapter3<T : Any>(private val itemLayoutViewId: Int, private var data: MutableList<T>, bindCall: View.(T, Int) -> Unit) :
    GenericBindableAdapter<T>(
        itemLayoutViewId, data, bindCall
    ) {

    override fun getItemViewType(position: Int): Int {
        return itemLayoutViewId
    }

    override fun getItemCount(): Int {
        return data.size
    }
}

//https://github.com/LRacoci/CoronaTracker/blob/b7b63677f53e6b4c3f7374d6858d0679ddef3c9a/app/src/main/java/com/github/coronatracker/ui/main/MainFragment.kt
open class GenericBindableAdapter<T : Any>(
    private var itemLayoutViewId: Int,
    private var data: MutableList<T>,
    private var bindCall: View.(T, Int) -> Unit
) :
    RecyclerView.Adapter<BindableViewHolder3<T>>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindableViewHolder3<T> {
        val layoutInflater = LayoutInflater.from(parent.context)
        val itemView = layoutInflater.inflate(itemLayoutViewId, parent, false)
        return object : BindableViewHolder3<T>(itemView) {
            override fun onBind(item: T, pos: Int) {
                itemView.bindCall(item, pos)
            }
        }
    }

    override fun onBindViewHolder(holder: BindableViewHolder3<T>, position: Int) {
        holder.bind(position, data[position])
    }

    override fun getItemCount() = data.size

    @SuppressLint("NotifyDataSetChanged")
    fun notifyDataSetChanged(list: List<T>) {
        data.clear()
        data.addAll(list)
        notifyDataSetChanged()
    }

    @SuppressLint("NotifyDataSetChanged")
    fun notifyDataSetCleared() {
        data.clear()
        notifyDataSetChanged()
    }
}

abstract class BindableViewHolder3<T : Any>(itemView: View) :
    RecyclerView.ViewHolder(itemView) {
    fun bind(pos: Int, item: T) {
        onBind(item, pos)
    }

    abstract fun onBind(item: T, pos: Int)
}

使用

ConcatBindableAdapter3(R.layout.listitem_product_image, image.toMutableList()) { item, pos ->
  Log.e("mgg", "onBindViewHolder: fail to get image resource id from name") 
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容