美文网首页
ConcatAdapter

ConcatAdapter

作者: CentForever | 来源:发表于2021-10-27 21:03 被阅读0次

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") 
}

相关文章

网友评论

      本文标题:ConcatAdapter

      本文链接:https://www.haomeiwen.com/subject/adipaltx.html