Usare le RecyclerView in Android con Kotlin

Mattepuffo's logo
Usare le RecyclerView in Android con Kotlin

Usare le RecyclerView in Android con Kotlin

Il componente per Android RecyclerView, è quello che sostituisce altri contenitori come ListView.

Se volete usare contenitori con dati "ripetuti" come liste, è altamente consigliato.

Oggi vediamo una sua implementazione in Kotlin; prenderemo i dati da web service in formato JSON usando Anko e Klaxon, e costruiremo un nostro adapter:

  • Anko ci serve per le richieste asincrone (e per il logging, ma non è strettamente necessario)
  • Klaxon per il parsing del JSON

Queste sono le dipendenze da agigungere a gradle:

dependencies {
	..................
    // AGGIUNTE
    implementation 'org.jetbrains.anko:anko-commons:0.10.4'
    implementation 'com.beust:klaxon:2.1.14'
    implementation 'com.android.support:recyclerview-v7:26.1.0'
    implementation 'com.android.support:cardview-v7:26.1.0'
}

Questo è il layout principale dell'Activity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:orientation="vertical"
    tools:context=".ClientiActivity">

    <Button
        android:id="@+id/btnCliente"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/clienti"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="49dp" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerViewClienti"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" />

</LinearLayout>

Adesso create un altro layout, che corrisponderà ai dati da visualizzare come lista:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="10dp">

            <TextView
                android:id="@+id/rag_soc"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <TextView
                android:id="@+id/codice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </LinearLayout>
    </android.support.v7.widget.CardView>

</LinearLayout>

Adesso passiamo a Kotlin; cominciamo con la nostra classe contenitore:

data class Cliente(val codice: Int, val ragSoc: String)

Nulla di complicato; qua aggiungete tutte le proprietà che volete, e che corrispondono ai dati presi dal JSON remoto.

Questo il nostro adapter:

import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView

class ClientiAdapter(val clientiList: ArrayList) : 
        RecyclerView.Adapter() {

    override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
        holder?.ragSoc?.text = clientiList[position].ragSoc
        holder?.codice?.text = clientiList[position].codice.toString()
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
        val v = LayoutInflater.from(parent?.context).inflate(
                R.layout.clienti_items, parent, false)
        return ViewHolder(v);
    }

    override fun getItemCount(): Int {
        return clientiList.size
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val ragSoc = itemView.findViewById(R.id.rag_soc)
        val codice = itemView.findViewById(R.id.codice)
    }
}

Infine il codice dell'Activity:

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.widget.LinearLayout
import com.beust.klaxon.Klaxon
import kotlinx.android.synthetic.main.activity_clienti.*
import org.jetbrains.anko.*
import java.net.URL

class ClientiActivity : AppCompatActivity(), AnkoLogger {

    private var finalUrl: String = "URL_WEB_SERVICE"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_clienti)

        btnCliente.setOnClickListener {
            val dialog = indeterminateProgressDialog(message = "Wait...",
                    title = "Recupero dati")
            doAsync {
                try {
                    var result = result = URL(finalUrl).readText()
         
                    uiThread {
                        var res = Klaxon().parseArray<Cliente>(result)
                        recyclerViewClienti.layoutManager = LinearLayoutManager(
                                applicationContext, LinearLayout.VERTICAL, false
                        )
                        var adapter = ClientiAdapter(res as ArrayList<Cliente>)
                        recyclerViewClienti.adapter = adapter
                        dialog.dismiss()
                    }
                } catch (e: Exception) {
                    uiThread {
                        dialog.dismiss()
                        longToast(e.message.toString())
                    }
                }

            }
        }
    }
}

Al click sul Button visualiziamo un indeterminateProgressDialog, e avviamo la richiesta asinrona.

Prendiamo i dati, facciamo il parsing del JSON ed effettuiamo il binding con la nostra classe wrapper.

Infine riampiamo l'adapter e lo impostiamo per il nostro RecyclerView.

Enjoy!


Condividi

Commentami!