实现非常简单,主要运用了databinding的特性实现,使用非常简单
https://github.com/TianGuisen/KtBindAdapter
使用方法
item布局中必须这样写,name="item",否则baseAdapter中BR.item会报错无法使用
<data>
<variable
name="item"
type="绑定的实体类"></variable>
</data>
创建adapter
//单type,直接创建SimpleAdapter即可,没有item子view的点击事件
val testAdapter = SimpleAdapter(listData, R.layout.item_sigle1)
//多type
val itemInfos = mutableListOf<MultiItem<ItemInfo>>()
val multiAdapter = SimpleMultiAdapter(itemInfos)
//添加布局
multiAdapter.addItemType(TYPE0, R.layout.item_type0)
multiAdapter.addItemType(TYPE1, R.layout.item_type1)
//
multiAdapter.setOnItemClickLisener { multiItem: MultiItem<ItemInfo>, view: View, i: Int ->
ToastUtil.normal("点击的是item:" + multiItem + " 位置:" + i)
}
实现
abstract class BaseAdapter<E : Any, VB : ViewDataBinding> internal constructor(datas: MutableList<E>) : RecyclerView.Adapter<BindViewHolder<VB>>() {
internal var mDatas: MutableList<E> = datas
internal var itemClickLisener: OnItemClickLisener<E>? = null
internal var childClickLisener: OnChildClickLisener<E>? = null
internal var itemLongClickLisener: OnItemLongClickLisener<E>? = null
fun setChildClickLisener(function: (E, View, Int) -> Unit) {
this.childClickLisener = object : OnChildClickLisener<E> {
override fun childClick(bean: E, view: View, position: Int) {
function(bean, view, position)
}
}
}
fun setOnItemClickLisener(itemClickLisener: OnItemClickLisener<E>) {
this.itemClickLisener = itemClickLisener
}
fun setOnItemClickLisener(function: (E, View, Int) -> Unit) {
this.itemClickLisener = object : OnItemClickLisener<E> {
override fun itemClick(bean: E, view: View, position: Int) {
function(bean, view, position)
}
}
}
fun setItemLongClickLisener(function: (E, View, Int) -> Unit) {
this.itemLongClickLisener = object : OnItemLongClickLisener<E> {
override fun itemLongClick(bean: E, view: View, position: Int) {
function(bean, view, position)
}
}
}
interface OnItemClickLisener<E> {
fun itemClick(bean: E, view: View, position: Int)
}
interface OnChildClickLisener<E> {
fun childClick(bean: E, view: View, position: Int)
}
interface OnItemLongClickLisener<E> {
fun itemLongClick(bean: E, view: View, position: Int)
}
override fun onBindViewHolder(holder: BindViewHolder<VB>, position: Int) {
val bean = mDatas[position]
val itemView = holder.binding.getRoot()
if (itemClickLisener != null) {
itemView.setOnClickListener {
itemClickLisener!!.itemClick(bean, holder.binding.getRoot(), position)
}
}
decorator(bean, holder, position)
//如果是BaseMultiAdapter需要处理一下
if (mDatas[position] is MultiItem<*>) {
val pinnedHeaderEntity = mDatas[position] as MultiItem<*>
holder.binding.setVariable(item, pinnedHeaderEntity.data)
} else {
holder.binding.setVariable(item, mDatas[position])
}
holder.binding.executePendingBindings()
}
abstract fun decorator(bean: E, holder: BindViewHolder<VB>, position: Int)
open fun remove(position: Int) {
mDatas.removeAt(position)
notifyItemRemoved(position)
}
open fun clear() {
mDatas.clear()
notifyDataSetChanged()
}
override fun getItemCount(): Int {
return mDatas.size
}
}
/**
* 单type
* 如果item内容填充较复杂,无法在item的xml中完成,需要在decorator完成填充,就使用这个
* 或者需要子view的点击事件使用这个
*/
open abstract class BaseSigleAdapter<E : Any, VB : ViewDataBinding> : BaseAdapter<E, VB> {
private var layoutId: Int = 0
constructor(datas: MutableList<E>, layoutId: Int) : super(datas) {
this.layoutId = layoutId
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindViewHolder<VB> {
val binding = DataBindingUtil.inflate<VB>(LayoutInflater.from(parent.context), layoutId, parent, false)
return BindViewHolder(binding.root, binding)
}
fun add(data: E) {
mDatas.add(data)
notifyDataSetChanged()
}
fun add(position: Int, data: E) {
mDatas.add(position, data)
notifyDataSetChanged()
}
fun set(data: List<E>) {
mDatas.clear()
addAll(data)
}
fun addAll(data: List<E>) {
mDatas.addAll(data)
notifyDataSetChanged()
}
}
/**
* 多type
* 如果item内容填充较复杂,无法在item的xml中完成,需要在decorator完成填充,就使用这个
* 或者需要子view的点击事件使用这个
*/
open abstract class BaseMultiAdapter<E : Any> : BaseAdapter<MultiItem<E>, ViewDataBinding> {
constructor(data: MutableList<MultiItem<E>>) : super(data)
private val layouts: SparseIntArray = SparseIntArray()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindViewHolder<ViewDataBinding> {
val binding = DataBindingUtil.inflate<ViewDataBinding>(LayoutInflater.from(parent.context), layouts.get(viewType), parent, false)
onCreateViewHolderDecorate(binding, viewType)
return BindViewHolder(binding.root, binding)
}
open fun onCreateViewHolderDecorate(view: ViewDataBinding, viewType: Int) {
}
override fun getItemViewType(position: Int): Int {
return mDatas.get(position).itemType
}
fun addItemType(type: Int, @LayoutRes layoutResId: Int) {
layouts.put(type, layoutResId)
}
}
class BindViewHolder<VB>(itemView: View, val binding: VB) : RecyclerView.ViewHolder(itemView)
/**
* 多type的需要用这个包装实体类
*/
class MultiItem<T>(var itemType: Int, var data: T) {
override fun toString(): String {
return "MultiItem(itemType=$itemType, data=$data)"
}
}
/**
* Created by 田桂森 on 2017/8/17.
* 如果不需要设置item中子类点击事件用这个
*/
class SimpleAdapter<E : Any>(datas: MutableList<E>, layoutId: Int) : BaseSigleAdapter<E, ViewDataBinding>(datas, layoutId) {
override fun decorator(bean: E, holder: BindViewHolder<ViewDataBinding>, position: Int) {
}
}
/**
* Created by 田桂森 on 2017/8/18.
* 多type如果不需要设置item中子类子类点击事件用这个
*/
class SimpleMultiAdapter<E : Any>(datas: MutableList<MultiItem<E>>) : BaseMultiAdapter<E>(datas) {
override fun decorator(bean: MultiItem<E>, holder: BindViewHolder<ViewDataBinding>, position: Int) {
}
}
网友评论