美文网首页
MVVM下databinding通用RecyclerView适配

MVVM下databinding通用RecyclerView适配

作者: 御坂七十一号 | 来源:发表于2020-09-21 17:44 被阅读0次

adapter主要代码

package com.bkex.common.base

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.IdRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import com.bkex.common.utils.Utils
import java.lang.reflect.ParameterizedType

/**
 * @author 作者 zbb
 * @version 创建时间:2020/5/8 9:45
 */
abstract class BaseRvDatabindingAdapter<T : Any, VH : BaseRvDatabindingAdapter.BaseRvDatabindingViewHolder<BD>, BD : ViewDataBinding>(
    var context: Context?,
    var list: ArrayList<T>
) :
    RecyclerView.Adapter<VH>() {
    constructor(context: Context?) : this(context, ArrayList<T>())

    val TAG = "BaseRvDatabindingAdapter"

    var onItemClickListener: OnItemClickListener<T>? = null
    var onItemLongClickListener: OnItemLongClickListener<T>? = null

    var onViewClickListener: View.OnClickListener? = null
    var onViewLongClickListener: View.OnLongClickListener? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
//        var clz2 = Utils.getTClass(this)[2] as Class<T>
        var databinding = DataBindingUtil.inflate<BD>(
            LayoutInflater.from(context),
            getLayoutId(viewType),
            parent,
            false
        )
        var types = Utils.getTClass(this)
        var clz: Class<VH>
        /**
         * 如果外面传入的是BaseRvDatabindingAdapter.BaseRvDatabindingViewHolder<ViewDataBinding>,带泛型的,
         * 它接收到的就是ParameterizedType,否则就是Class<>
         */
        if (types[1] is ParameterizedType) {
            var parameterizedType = types[1] as ParameterizedType
            clz = parameterizedType.rawType as Class<VH>
        } else {
            clz = types[1] as Class<VH>
        }
        var clz2 = types[2] as Class<BD>
        var mCreate = clz.getConstructor(clz2)
        return mCreate.newInstance(databinding) as VH
    }


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

    override fun onBindViewHolder(holder: VH, position: Int) {
        bindData(holder.binding, position)
        holder.binding.executePendingBindings()
//        LogUtils.i(TAG, Throwable(),"onItemClickListener="+onItemClickListener)
        //对 ItemView 设置监听器,不要对每个 Item 都调用 addXxListener,应该大家公用一个 XxListener,
        // 根据 ID 来进行不同的操作,优化了对象的频繁创建带来的资源消耗。
        holder.binding.root.setTag(position)
        if (onViewClickListener == null) {
            onViewClickListener = View.OnClickListener {
                var position = (it.getTag() as Int)
                onItemClickListener?.onItemClick(position, list.get(position))
            }
        }
        holder.binding.root.setOnClickListener(onViewClickListener)

        if (onViewLongClickListener == null) {
            onViewLongClickListener = View.OnLongClickListener {
                var position = (it.getTag() as Int)
                return@OnLongClickListener onItemLongClickListener?.onItemLongClick(
                    position,
                    list.get(position)
                ) ?: false
            }
        }
        holder.binding.root.setOnLongClickListener(onViewLongClickListener)
    }

    abstract fun getLayoutId(@IdRes layoutId: Int): Int

    abstract fun bindData(binding: BD, position: Int)

    fun addItem(entity: T) {
        list.add(entity)
        notifyDataSetChanged()
    }

    fun addItem(entity: T, position: Int) {
        list.add(position, entity)
        notifyItemInserted(position)
    }

    fun removeItem(position: Int) {
        list.removeAt(position)
        notifyItemMoved(position, position + 1);
        notifyItemChanged(position, list.size - 1)
    }

    fun changeItem(entity: T, position: Int) {
        list.set(position, entity)
        notifyItemChanged(position)
    }

    open class BaseRvDatabindingViewHolder<BD : ViewDataBinding> constructor(var binding: BD) :
        RecyclerView.ViewHolder(binding.root) {
    }

    interface OnItemClickListener<T> {
        fun onItemClick(position: Int, obj: T)
    }

    interface OnItemLongClickListener<T> {
        fun onItemLongClick(position: Int, obj: T): Boolean
    }
}

使用到的utils工具类方法

 fun getTClass(obj: Any): Array<Type> {
            val type: ParameterizedType? =
                obj.javaClass.getGenericSuperclass() as ParameterizedType?
            return type!!.actualTypeArguments
        }

1.普通使用

package com.zbb.mine.adapter

import android.content.Context
import androidx.databinding.ViewDataBinding
import com.bkex.common.base.BaseRvDatabindingAdapter
import com.zbb.mine.BR
import com.zbb.mine.R
import com.zbb.mine.entity.GroupEntity

class RvMusicGroupAdapter(context: Context?, group: ArrayList<GroupEntity>) :
    BaseRvDatabindingAdapter<GroupEntity,BaseRvDatabindingAdapter.BaseRvDatabindingViewHolder<ViewDataBinding>,ViewDataBinding>(context, group) {

    override fun getLayoutId(layoutId: Int): Int {
        return R.layout.item_rv_group
    }

    override fun bindData(binding: ViewDataBinding, position: Int) {
        binding.setVariable(BR.item,list[position])
    }
}

2.如果有特殊需要操作item中的view的话,使用第二种方便获取item中某个view对象,省掉findViewById那一步:

package com.zbb.mine.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import com.bkex.common.base.BaseRvDatabindingAdapter
import com.bkex.common.utils.Utils
import com.zbb.mine.R
import com.zbb.mine.BR
import com.zbb.mine.databinding.DialogMusicMenuBinding
import com.zbb.mine.databinding.ItemRvLocalMusicBinding
import com.zbb.mine.entity.MusicEntity

class RvLocalMusicAdapter(context: Context, list: ArrayList<MusicEntity>) :
    BaseRvDatabindingAdapter<MusicEntity, RvLocalMusicAdapter.ViewHolder,ItemRvLocalMusicBinding>(context, list) {
    var onMoreClickListener: OnItemMenuClickListener?=null

    override fun getLayoutId(layoutId: Int): Int {
        return R.layout.item_rv_local_music
    }

    class ViewHolder(binding: ItemRvLocalMusicBinding):BaseRvDatabindingViewHolder<ItemRvLocalMusicBinding>(binding){

    }

    override fun bindData(binding: ItemRvLocalMusicBinding, position: Int) {
        binding.setVariable(BR.item, list[position])
        //此处对item中的view示例操作
        binding.待操作的view.xxxx做操作
    }
    interface OnItemMenuClickListener{
       fun onItemMenuClick(entity:MusicEntity)
    }
}

如果只是简单使用,不需要获取item中view进行其他操作,BaseRvDatabindingAdapter也可以不用VH和BD,直接在BaseRvDatabindingAdapter里面使用默认的BaseRvDatabindingViewHolder和viewDatabinding就好了。

完事。

相关文章

网友评论

      本文标题:MVVM下databinding通用RecyclerView适配

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