RecyclerView Selection & MyAdapter 构建随意选择数据的RecyclerView

MyAdapter

自定义可复用ViewAdapter,在前一篇博客里,不多说了。下面是MyAdapter的代码,T就是list里面装的数据的type

//T: The list data type
abstract class MyViewAdapter<T>(diffCallback: DiffUtil.ItemCallback<T>)
    : ListAdapter<T, MyViewHolder<T>>(diffCallback){
    
    
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder<T> {
    
    
        val layoutInflater = LayoutInflater.from(parent.context)
        val binding = DataBindingUtil
            .inflate<ViewDataBinding>(layoutInflater, viewType, parent, false)
        return MyViewHolder(binding)
    }

    override fun onBindViewHolder(holder: MyViewHolder<T>, position: Int) {
    
    
        holder.bind(getItem(position))
        onClick(holder, tracker)
    }
    
	class MyViewHolder<T>(val binding: ViewDataBinding)
    	: RecyclerView.ViewHolder(binding.root){
    
    

    	fun bind(item: T){
    
    
     	   binding.setVariable(BR.item, item)
     	   binding.executePendingBindings()
   	 	}
	}
}

RecyclerView-Selection

这是一个lib,详情参照官方文档Enable list-item selection,或者这一篇文章A guide to recyclerview-selection。如果已经学会了使用这个lib,就往下看,你会看得懂这样的代码,其实就在Adapter里放了一个TrackerTracker的初始化略,但要注意一点,必须先初始化RecyclerView,然后RecyclerViewAdapter,最后才是TrackerAapter初始化必须在Tracker之前,Tracker初始化会用到RecyclerView,在其内部代码中RecyclerView会引用它的Adapter,作为初始化参数,这个时候如果Adapter为空就会Error

abstract class MyViewAdapter<T>(diffCallback: DiffUtil.ItemCallback<T>)
    : ListAdapter<T, MyViewHolder<T>>(diffCallback){
    
    

    var tracker: SelectionTracker<Long>? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder<T> {
    
    
        val layoutInflater = LayoutInflater.from(parent.context)
        val binding = DataBindingUtil
            .inflate<ViewDataBinding>(layoutInflater, viewType, parent, false)
        return MyViewHolder(binding)
    }

    override fun onBindViewHolder(holder: MyViewHolder<T>, position: Int) {
    
    
        holder.bind(getItem(position))
    }
}

这个lib,通过tracker来记录你在recyclerView中选择的item。有单选和多选两种模式,但是要开启选择必须要长按,才能触发selection。所以如果要避开长按,那么就得手动调用tracker的select方法。也就是说,要监听RecyclerView里面的点击事件。

监听RecyclerView里Item的点击事件

由于MyAdapter抽象类,我并不想只让MyAdapter完成一种点击事件的处理。所以,我在MyAdapter里面写了一个抽象方法onClick(holder: MyViewHolder<T>)


override fun onBindViewHolder(holder: MyViewHolder<T>, position: Int) {
    
    
        holder.bind(getItem(position)) 
        holder.binding.root.setOnClickListener {
    
    
     		onClick()
    }
}
abstract fun onClick()

实现的一小段代码,就可以在这个Adapter里自定义逻辑了

class AvatarAdapter: MyViewAdapter<String>(DiffCallBack()){
    
    
	......
    override fun onClick() {
    
    
        
    }
    ......
}

当然上面是无法对当前点击的位置的view进行操作的,因为没有传参数
于是,改进

override fun onBindViewHolder(holder: MyViewHolder<T>, position: Int) {
    
    
        holder.bind(getItem(position)) 
        holder.binding.root.setOnClickListener {
    
    
     		onClick(holder)
    }
}
abstract fun onClick(holder: MyViewHolder<T>)

这样之后,就可以通过获取Binding对view进行操作了,设置isCheckedvisibletext等等

class AvatarAdapter: MyViewAdapter<String>(DiffCallBack()){
    
    
	......
    override fun onClick(holder: MyViewHolder<T>) {
    
    
        holder.binding.xxxx
    }
    ......
}

手动select

将之前的onClick()小改一下

abstract fun onClick(holder: MyViewHolder<T>, tracker: SelectionTracker<Long>?)

实现,被点击的时候,调用select方法,传入Key。这里的Key就是holder.itemId。这样就手动将被点击的item放到selection里面了

class AvatarAdapter: MyViewAdapter<String>(DiffCallBack()){
    
    
	......
    override fun onClick(holder: MyViewHolder<String>, tracker: SelectionTracker<Long>?) {
    
    
            tracker?.select(holder.itemId)
    }
	......
}

猜你喜欢

转载自blog.csdn.net/qq_43709922/article/details/104420957