MergeAdapter es una nueva clase introducida en RecyclerView: 1.2.0-alpha02 que le permitirá combinar varios adaptadores de pantalla en un solo RecyclerView. Esto le permitirá encapsular la lógica de cada celda en su adaptador y le permitirá reutilizarla en el futuro.
Problema
Comencemos con un ejemplo. Supongamos que tenemos la tarea de mostrar un feed con dos tipos de datos: un texto con una descripción y una imagen. El código del método
onCreateViewHolder en el caso más común se verá así:
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int
): RecyclerView.ViewHolder? {
val holder: RecyclerView.ViewHolder
val inflater = LayoutInflater.from(parent.context)
when (viewType) {
TEXT_VIEW_TYPE -> {
holder = TextViewHolder(
inflater.inflate(R.layout.text_item, parent, false)
)
}
IMAGE_VIEW_TYPE -> {
holder = ImageViewHolder(
inflater.inflate(R.layout.image_item, parent, false),
imageClickListener
)
}
else -> {
throw IllegalArgumentException(
"Can't create view holder from view type $viewType"
)
}
}
return holder
}
¿Por qué es tan malo? La desventaja de esta implementación es la violación de los principios de SECO y SÓLIDO (responsabilidad única y abierto cerrado). Para convencerse de esto, basta con agregar dos requisitos: ingresar un nuevo tipo de datos (casilla de verificación) y otra cinta, donde solo habrá casillas de verificación e imágenes.
Nos enfrentamos a una elección: ¿utilizar el mismo adaptador para la segunda cinta o crear una nueva? Independientemente de la solución que elijamos, tendremos que cambiar el código (casi lo mismo, pero en diferentes lugares). Será necesario añadir un nuevo VIEW_TYPE, ViewHolder nuevos y editar métodos:
getItemViewType(), onCreateViewHolder() onBindViewHolder().
Si decidimos mantener un adaptador, los cambios terminarán ahí. Pero si en el futuro se agregarán nuevos tipos de datos con nueva lógica solo al segundo feed, el primero tendrá funcionalidad adicional y también deberá probarse, aunque no ha cambiado.
Si decidimos crear un nuevo adaptador, habrá mucho código duplicado.
Decisión
La nueva clase MergeAdapter le permite combinar diferentes adaptadores para diferentes tipos de celdas. Por ejemplo, un caso de uso muy común es mostrar una ruleta mientras se cargan datos en el feed y, si, de repente, se produce un error de carga, se muestra una celda con un error al final del feed.
La solución a este problema puede ser el uso de MergeAdapter Supongamos que tenemos 3 adaptadores:
val firstAdapter: FirstAdapter = …
val secondAdapter: SecondAdapter = …
val thirdAdapter: ThirdAdapter = …val mergeAdapter = MergeAdapter(firstAdapter, secondAdapter, thirdAdapter)
recyclerView.adapter = mergeAdapter
RecyclerView mostrará los elementos de cada adaptador de forma secuencial, en el mismo orden en que se pasaron al constructor. Los diferentes adaptadores le permiten separar la lógica para diferentes celdas de la lista. Por ejemplo, si necesita agregar un título a la lista, no necesita implementar esta lógica en el adaptador, que es responsable de mostrar el contenido principal en la lista, puede separar los adaptadores para diferentes tipos de celdas. Este enfoque ayuda a encapsular la lógica y reutilizarla en el futuro para diferentes pantallas.
Muestre la descarga en el encabezado o al final de la lista.
Para mostrar el estado de descarga en la parte superior o inferior de la lista, debe agregar adaptadores, respectivamente:
val mergeAdapter = MergeAdapter(headerAdapter, listAdapter, footerAdapter)
recyclerView.adapter = mergeAdapter
La celda superior y la inferior usan el mismo diseño, ViewHolder y lógica UI (mostrar estado de carga y ocultar). En general, sería suficiente usar 2 instancias del mismo adaptador para la parte superior e inferior de la lista. Puede encontrar un ejemplo aquí o aquí .
En definitiva, de una forma tan sencilla puedes mejorar el código de tu proyecto si utilizas un adaptador complejo con diferentes tipos de celdas.
¿Te gustó el artículo? No olvide unirse a nosotros en Telegram , y en la plataforma AndroidSchool.ru se publican materiales útiles para desarrolladores de Android y tutoriales modernos.