Make writing a habit together! This is the 12th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

Before written an article based on BaseRecyclerViewAdapterHelper and ViewBinding climb hole trip to encapsulate the article, mainly based on BRVAH and ViewBinding encapsulation adapter:

One disadvantage of this encapsulation is that ViewBinding requires subclass Adapter to override createViewBinding() and pass in the created ViewBinding instance.

Koltin itself supports function types, that is, methods can be passed as parameters. To take advantage of this feature, we can re-wrap the above encapsulated adapter.

1. The function type passes the ViewBinding creation method

We define a function type to create a ViewBinding:

val mBinding: (LayoutInflater, ViewGroup, Boolean) -> VB
Copy the code

The viewbinding.inflate method itself can be converted to the function type we define, as long as the method parameter signature and the return value type are the same.

We define the function type that creates the ViewBinding concrete instance as the BaseBindingAdapter construction parameter:

abstract class BaseBindingAdapter<VB: ViewBinding, T>(val binding: (LayoutInflater, ViewGroup, Boolean) -> VB,
                                                      data: MutableList<T>? = null):
}
Copy the code

Then we can use it externally like this:

class TestAdapter: BaseBindingAdapter<ActivityChapterBinding, String>(ActivityChapterBinding::inflate) {
    override fun convertPlus(binding: ActivityChapterBinding, item: String){}}Copy the code

As you can see, instead of overwriting the createViewBinding() method to create a ViewBinding, you simply pass in the ViewBinding::inflate as the construction parameter.

2. BRVAHthesetOnItemClickListenerWhat is passed by the position argument in

Find the answer directly from the BRVAH source:

// Set the click event
override fun setOnItemClickListener(listener: OnItemClickListener?). {
    this.mOnItemClickListener = listener
}

// Trigger mOnItemClickListener to click the event callback
protected open fun setOnItemClick(v: View, position: Int){ mOnItemClickListener? .onItemClick(this, v, position)
}

Call the setOnItemClick method
protected open fun bindViewClickListener(viewHolder: VH, viewType: Int){ mOnItemClickListener? .let { viewHolder.itemView.setOnClickListener { v ->// Get the position argument
            varposition = viewHolder.adapterPosition ... SetOnItemClick (v, position)}}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
    bindViewClickListener(viewHolder, viewType)
}
Copy the code

The click event callback we set up in setOnItemClickListener() is finally called in the bindViewClickListener() method. BindViewClickListener () is called from the familiar onCreateViewHolder().

Why not set the click event to call mOnItemClickListener in onBindViewHolder() so that the position of onBindViewHolder() can be used directly?

There are two ways to answer this question:

  • Angle of reuse ViewHolder: If the ViewHolder is recycled into the RecycleViewPool and needs to be reused, onBindViewHolder() is used to bind data again, but this has nothing to do with the click event setting, so onCreateViewHolder is used to avoid duplication

  • Position Correctly obtained Angle: Can see from the source, transfer to the position parameters of mOnItemClickListener callback is through the viewHolder adapterPosition access, do not rely on onBindViewHolder () parameters of the position.

On the second point, even if the click event is placed into the onBindViewHolder() setting, it does not depend on the position in its argument. Why?

For example, if there are currently three items: A, B, and C: After deleting A and the data in the data source set of A, if the position used in the click event is onBindViewHolder(), then the position obtained from B will still be 1, so the data of C will be used incorrectly (because A has been deleted, Position 1 corresponds to the data of C);

And if you are using viewHolder adapterPosition, then click B position can get correct position 0, click event properly implemented according to the expected effect

Refer to the article

Based on BaseRecyclerViewAdapterHelper and ViewBinding pit package tour