"Colisión" secundaria entre BRVAH y ViewBinding

¡Acostúmbrate a escribir juntos! Este es el día 12 de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de abril", haga clic para ver los detalles del evento .

Escribí un artículo anterior basado en el artículo BaseRecyclerViewAdapterHelper y ViewBinding Climbing Encapsulation Tour , principalmente para explicar el adaptador de paquete basado en BRVAH y ViewBinding:

imagen.png

createViewBinding()Este tipo de encapsulación tiene una desventaja: ViewBinding debe pasarse en la instancia de ViewBinding creada específicamente por el método de reescritura del adaptador de la subclase , que es más problemático de escribir.

El propio Koltin admite tipos de funciones, es decir, si 可以将方法作为参数进行传递usamos esta función, encapsularemos el adaptador encapsulado anteriormente.

1. El tipo de función pasa el método de creación ViewBinding

Definimos un tipo de función para crear ViewBinding:

val mBinding: (LayoutInflater, ViewGroup, Boolean) -> VB
复制代码

ViewBinding.inflateEl método en sí se puede convertir al tipo de función que definimos, siempre que la firma del parámetro del método y el tipo de valor devuelto sean los mismos.

Definimos este tipo de función que crea una instancia concreta de ViewBinding como BaseBindingAdapterparámetro del constructor:

abstract class BaseBindingAdapter<VB: ViewBinding, T>(val binding: (LayoutInflater, ViewGroup, Boolean) -> VB,
                                                      data: MutableList<T>? = null):
}
复制代码

Entonces podemos usarlo externamente así:

class TestAdapter: BaseBindingAdapter<ActivityChapterBinding, String>(ActivityChapterBinding::inflate) {
    override fun convertPlus(binding: ActivityChapterBinding, item: String) {
    }
}
复制代码

Como puede ver, ya no necesitamos anular el método para createViewBinding()crear ViewBinding, sino que usamos directamente la referencia del método ViewBinding::inflatecomo un parámetro de construcción para pasar, ¡lo que parece mucho más conveniente! !

2. Lo que se pasa en el parámetro de posición BRVAHdesetOnItemClickListener

BRVAHEncuentre la respuesta directamente desde el código fuente:

//设置点击事件
override fun setOnItemClickListener(listener: OnItemClickListener?) {
    this.mOnItemClickListener = listener
}

//触发mOnItemClickListener点击事件回调调用
protected open fun setOnItemClick(v: View, position: Int) {
    mOnItemClickListener?.onItemClick(this, v, position)
}

//调用setOnItemClick方法
protected open fun bindViewClickListener(viewHolder: VH, viewType: Int) {
    mOnItemClickListener?.let {
        viewHolder.itemView.setOnClickListener { v ->
            //获取position参数
            var position = viewHolder.adapterPosition
            ...省略
            setOnItemClick(v, position)
        }
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
    bindViewClickListener(viewHolder, viewType)
}
复制代码

setOnItemClickListener()La devolución de llamada del evento de clic que configuramos finalmente se bindViewClickListener()llama en el método. Pero es en la llamada bindViewClickListener()que nos es familiar .onCreateViewHolder()

Pensemos en ello, ¿por qué no onBindViewHolder()establecer la llamada de evento de clic en el método , mOnItemClickListenerpara que pueda usarse directamente ?onBindViewHolder()position

Hay dos formas de responder a esta pregunta:

  • 回收复用ViewHolder的角度: si ViewHolder se recicla en RecycleViewPool y necesita ser reutilizado, necesita volver a onBindViewHolder()vincular los datos, pero esto no tiene nada que ver con la configuración del evento de clic. Para evitar configuraciones repetidas, se coloca en la onCreateViewHolderconfiguración.

  • position位置正确获取的角度: Como puede ver en el código fuente, los parámetros pasados ​​a la mOnItemClickListenerdevolución de llamada se obtienen al obtenerlos y no dependen de los parámetros .positionviewHolder.adapterPositiononBindViewHolder()position

En cuanto al segundo punto, aunque el evento de clic esté colocado onBindViewHolder()en la configuración, no dependerá de sus parámetros ¿A positionqué se debe esto?

Por ejemplo, si actualmente hay tres elementos: A, B, C, después de eliminar los datos en la colección de fuentes de datos donde se encuentran A y A, si el evento de clic usa los positionparámetros onBindViewHolder()en el parámetro, haga clic en B para obtenerlo. .sigue positionsiendo 1, por lo que los datos de C se utilizarán incorrectamente (porque A se ha eliminado, la posición de 1 corresponde a los datos de C);

Y si lo usa , puede obtener la posición correcta 0 viewHolder.adapterPositioncuando hace clic en B, y el evento de clic se puede ejecutar normalmente de acuerdo con el efecto esperado.position

Artículo de referencia

Basado en BaseRecyclerViewAdapterHelper y ViewBinding paquete turístico de escalada

Supongo que te gusta

Origin juejin.im/post/7085864118212624415
Recomendado
Clasificación