Escribiendo un Adapter de RecyclerView en Kotlin (KDA 16)

A
Antonio Leiva
4 min lectura

Una forma interesante de ver cómo Kotlin simplifica tu vida es la creación de un Adapter de un RecyclerView.

Verás que el código se puede organizar de tal forma que su lectura sea muy sencilla y que evite código redundante.

Si quieres empezar hoy, te recomiendo que le eches un vistazo a mi training gratuito, donde tendrás una hora y media de contenido para saber cuáles son tus siguientes pasos a dar para convertirte en un experto en Kotlin.

Training Revienta tu productividad en Android con Kotlin

Adapter de RecyclerView en Kotlin

Crearemos un Adapter que asignará un título y una imagen a una celda.

Va a ser un adaptador muy sencillo en el que no permitiremos la modificación de los items. Si queremos nuevos datos, crearemos un nuevo adapter y se lo asignaremos al RecyclerView.

El modelo

Utilizaremos un modelo también muy simple, que sólo necesita un identificador, el título y la url de la imagen.

Usaremos una data class, que si recuerdas ya las vimos hace unos cuantos artículos:

data class Item(val id: Long, val title: String, val url: String)

Con esto ya tenemos una clase con su constructor, sus propiedades inmutables, y otras funciones útiles como equals o hashCode implementados.

El Adapter

La estructura del Adapter sería la siguiente, autogenerando los métodos necesarios:

class MyAdapter : RecyclerView.Adapter() {
     
    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
    }

    override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
    }

    override fun getItemCount(): Int {
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}

Verás que he creado una clase ViewHolder, que extiende de la original.

Esto es porque el Adapter necesita una implementación de la clase original abstracta.

También que hay algunos elementos marcados como nullable. Esto es porque si la librería no está correctamente anotada con las anotaciones @Nullable y @NonNull, Kotlin no tiene forma de saber si se permiten nulos, y nos deja decidir a nosotros.

Si autogeneramos los métodos, por defecto dará por hecho que los valores son nullable.

Pero estudiando un poco la librería de soporte, sabemos que esos valores no son nulos, así que lo podemos quitar:

class MyAdapter : RecyclerView.Adapter() {
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    }

    override fun getItemCount(): Int {
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}

El constructor

El adapter necesita recibir por parámetro los items y un listener. El resultado es algo así:

class MyAdapter(val items: List<Item>, val listener: (Item) -> Unit)

La implementación de los métodos es muy sencilla. Estoy utilizando una función de extensión que creé en un artículo anterior para inflar la vista:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(parent.inflate(R.layout.view_item))

override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(items[position], listener)

override fun getItemCount() = items.size

Se pueden implementar los tres métodos con la forma contraída, obteniendo el resultado anterior. En tres líneas tenemos todo el adapter implementado.

Ahora a por la implementación del ViewHolder.

El ViewHolder

El ViewHolder se encargará de asignar los valores del modelo a las vistas correspondientes:

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(item: Item, listener: (Item) -> Unit) = with(itemView) {
        itemTitle.text = item.title
        itemImage.loadUrl(item.url)
        setOnClickListener { listener(item) }
    }
}

Todo lo que tenemos aquí ya lo hemos visto en otros artículos: la función with, el función de extensión loadUrl para los ImageView, el acceso a las vistas mediante Kotlin Android Extensions y la asignación del listener del click.

Asignación del adapter

Ya queda lo más sencillo: asignar el adapter a la vista

recycler.layoutManager = GridLayoutManager(this, 2)
recycler.adapter = MyAdapter(items) {
    toast("${it.title} Clicked")
}

La función final es listener, que recibe un item. El código simplemente imprimirá el título del elemento sobre el que se haga click.

Conclusión

Así de sencillo es implementar un Adapter de un RecyclerView en Kotlin.

Haciendo uso de unas cuantas de las herramientas que hemos aprendido hasta ahora, hemos simplificado hasta el mínimo el código necesario.

Si todo esto te apasiona tanto como a mí, te animo a que te apuntes a mi training gratuito donde te contaré todo lo que necesitas para aprender a crear tus Apps Android en Kotlin desde cero