Escribiendo un Adapter de RecyclerView en Kotlin (KDA 16)
Antonio Leiva

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, 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

Quizá también te interese…

Kotlin 1.5.0 : Las 5 novedades que puedes empezar a usar hoy

Kotlin 1.5.0 : Las 5 novedades que puedes empezar a usar hoy

Kotlin 1.5.0 ya está aquí, y como siempre trae una serie de novedades que te van a interesar muchísimo. Cabe destacar que a partir de ahora, de acuerdo las nuevas versiones de Kotlin se lanzarán cada 6 meses, independientemente de las nuevas funcionalidades que...

¿Qué es Kotlin y para qué sirve?

¿Qué es Kotlin y para qué sirve?

Kotlin es un lenguaje de programación de código abierto creado por JetBrains que se ha popularizado gracias a que se puede utilizar para programar aplicaciones Android. Pero si has llegado hasta aquí pensando que Kotlin solo se puede usar en Android, lo que te voy a...

2 formas de recolectar Flows en la UI que SÍ funcionan

2 formas de recolectar Flows en la UI que SÍ funcionan

En la serie de artículos sobre Programación Reactiva con Flow hemos visto muchos conceptos, y hemos aprendido cómo aplicarlos al desarrollo Android. Pero hay algo que no hemos hecho del todo bien. Esto es la recolección de Flows desde la Activity (o el Fragment, en...

2 Comentarios

  1. Luis Angel

    Hola!
    Yo suelo definir el layout manager en el xml y En Java ocupo una biblioteca que también me permite crear adapters en 3 líneas incluyendo escuchar el click, sólo debo importarla y ya. Entonces, ¿Con kotlin debo implementar las funciones vistas en cada proyecto? Porque aún no me queda claro el alcance de las funciones y donde pueden vivir.

    Gracias

    Responder
    • Antonio Leiva

      Lo que uses en Java lo puedes seguir usando en Kotlin.

      Responder

Enviar un comentario

Los datos personales que proporciones a través de este formulario quedarán registrados en un fichero de Antonio Leiva Gordillo, con el fin de gestionar los comentarios que realizas en este blog. La legitimación se realiza a través del consentimiento de la parte interesada. Si no se acepta, no podrás comentar en este blog. Los datos que proporciona solo se utilizan para evitar el correo no deseado y no se usarán para nada más. Puede ejercer los derechos de acceso, rectificación, cancelación y oposición en contacto@devexperto.com.

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Acepto la política de privacidad *