Skip to content

Instantly share code, notes, and snippets.

@Krosxx
Created July 16, 2020 06:26
Show Gist options
  • Save Krosxx/1ea1efd1011e5c61792b4d5cc9790c94 to your computer and use it in GitHub Desktop.
Save Krosxx/1ea1efd1011e5c61792b4d5cc9790c94 to your computer and use it in GitHub Desktop.
DataBindingAdapter for RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import kotlin.reflect.KClass
/**
* # MultiTypeBindingAdapter
*
* Created on 2020/6/16
* @author Vove
*/
fun multiTypeBindingAdapter(
dataSet: List<Any>,
dbIdLayoutGetter: (item: Any) -> Pair<Int, Int>
): MultiTypeBindingAdapter {
return MultiTypeBindingAdapter(dataSet, dbIdLayoutGetter)
}
fun <T : Any> bindingAdapter(
dataSet: List<T>,
dbId: Int,
layId: Int
): BindingAdapter<T> = BindingAdapter(dataSet, dbId, layId)
open class MultiTypeBindingAdapter(
private val dataSet: List<Any>,
val dbIdLayoutGetter: (typeCls: KClass<*>) -> Pair<Int, Int>
) : RecyclerView.Adapter<BindingViewHolder>() {
private val typeMap = mutableMapOf<Int, KClass<*>>()
private fun getItem(p: Int): Any = dataSet[p]
override fun getItemViewType(position: Int): Int {
val type = (getItem(position) as Object).`class`.name.hashCode()
typeMap[type] = getItem(position)::class
return type
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder {
val (dbId, lId) = dbIdLayoutGetter(typeMap[viewType]!!)
val binding = DataBindingUtil.inflate<ViewDataBinding>(
LayoutInflater.from(parent.context),
lId,
parent,
false
)
return BindingViewHolder(binding.root.also {
it.setTag(R.id.tag_adapter_databinding_support, binding)
}, dbId)
}
override fun getItemCount(): Int = dataSet.size
override fun onBindViewHolder(holder: BindingViewHolder, position: Int) {
holder.binding.apply {
setVariable(holder.dbId, dataSet[position])
executePendingBindings()
}
}
}
open class BindingAdapter<T : Any>(
dataSet: List<T>,
private val dbId: Int,
private val layId: Int
) : MultiTypeBindingAdapter(dataSet, { dbId to layId })
class BindingViewHolder(itemView: View, val dbId: Int) : RecyclerView.ViewHolder(itemView) {
val binding: ViewDataBinding
get() = itemView.getTag(R.id.tag_adapter_databinding_support) as ViewDataBinding
}
@Krosxx
Copy link
Author

Krosxx commented Jul 16, 2020

多种布局类型:

添加一个数据类:

data class ListItem2(val icon: String)

布局 item_demo_list2.xml 省略...

创建Adapter:

recyclerView.adapter = multiTypeBindingAdapter(multiList) { kcls ->
    when (kcls) {
        ListItem::class -> BR.item to R.layout.item_demo_list
        ListItem2::class -> BR.item2 to R.layout.item_demo_list2
        else -> throw Exception("unsupport type $kcls")
    }
}

@Krosxx
Copy link
Author

Krosxx commented Jul 16, 2020

也可以继承其他已封装的Adapter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment