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!
android kotlin activity anko json klaxon indeterminateprogressdialog recyclerview adapter
Commentami!