Created
July 16, 2020 06:26
-
-
Save Krosxx/1ea1efd1011e5c61792b4d5cc9790c94 to your computer and use it in GitHub Desktop.
DataBindingAdapter for RecyclerView
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
多种布局类型:
添加一个数据类:
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")
}
}
也可以继承其他已封装的Adapter
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
单一类型数据
数据类:
列表布局(item_demo_list.xml):
创建
Adapter
: