RecyclerView és l'objecte adequat per a visualitzar llargues llistes d'objectes en les darreres versions d'Android. Similarment a Android ListVieẉ però amb un funcionament una mica més sofisticat, la idea segueix sent reciclar les «targetes» de visualització de cada item per estalviar RAM. Seguint el paradigma MVC, necessitarà un objecte intermig Adapter que ens enllaça la part gràfica amb la part de model.
Referències:
View intenta seguir un paradigma Model - Vista - Controlador.ArrayList) connectat directament a la View (ja sigui ListView o RecyclerView).Activity) o en una classe derivada de la View.Adapter. Aquest és l'element que coneix la View i el nostre Model i que ha de saber com reciclar els ítems per a l'estalvi de RAM.
Exemple: agenda de contactes
Volem fer una aplicació d'agenda de contactes simple. Amb nom i telèfon n'hi haurà prou per al model de contacte.
Seguirem les indicacions de la doc oficial d'Android de RecyclerView.
Haureu de crear els següents arxius o objectes:
Contact.kt: pel model de contacte (nom i telèfon al menys).ContactAdapter.kt: necessari per fer funcionar la RecyclerView. Seguirem el codi d'exemple de la doc.contact_item.xml: layout particularitzat per cada item de contacte a la llista. Preferiblement utilitzant LinearLayout vertical. Crearem un nou arxiu a res → layout.dataset : el més directe és implementar una ArrayList<Contact>. Es crearà dins de MainActivity.Us deixo algunes pistes per facilitar la implementació:
MainActivity: el més senzill seria una ArrayList<Contact>.RecyclerView.Contact i ContactAdapter. Podeu fer click dret sobre la carpeta principal del projecte i fer New → Kotlin Class/File.Contact: com a mínim ha de tenir nom i telèfon.'Activity (a activity_main.xml).TextView del main template per evitar confusions de IDs, o com a mínim modificar el seu ID amb un nom que no sigui el típic textView per quelcom més particularitzat.RecyclerView : text_row_layout.xml si voleu seguir la nomenclatura de la doc o contact_item.xml podria ser més adequat. Podeu crear-lo amb el botó dret sobre res → layout i fer New → Layout Resource File.ConstraintLayout per una simple LinearLayout vertical.TextViews pels elements que hagueu posat a la classe Contact: nom i telèfon com a mínim.CustomAdapter de la doc al ContactAdapter (canviant el nom de la class). Adapteu el què us calgui, en particular el nom dels camps a visualitzar: nom i telèfon (a l'exemple només hi ha 1 camp).
Si no veieu elements de la llista al RecyclerView, revisa:
LayoutManager al codi de l'Activity, sense aquest element no funciona el RecyclerView (l'exemple de la doc oficial no el té).RecyclerView no estigui massa ajustat al top del layout de la Activity. Posa un marge més gran perquè la StatusBar pot amagar els elements.textView.Un cop en funcionament, pots sofisticar la visualització:
item_layout.xml i afegint-hi elements com ImageView, etc.GridLayoutManager enlloc del LinearLayoutManager.
Mini Agenda
Implementa una agenda de contactes com s'ha descrit mes amunt.
Afegeix un botó flotant o Floating Action Button (FAB) com es descriu a la doc. El botó ens obrirà un Dialog per afegir un nou contacte.
Galeria d'imatges
Implementa una aplicació de captació d'imatges com la descrita a Android Camera que s'enregistrin en l'espai d'emmagatzematge compartit de l'aplicació.
Visualitza les imatges enregistrades en una nova Activity que visualitzi a mode de «galeria d'imatges» pròpies de la nostra app.
El dataset pot ser una llista d'elements File que podem llistar de l'espai d'emmagatzematge compartit de la nostra aplicació.
La implementació amb funcions lambda és més sofisticada, i té l'avantatge de tenir el codi més curt.
Per implementar un onClick cal modificar:
CustomAdapterCustomAdapter a la Activity (amb la funció lambda)
A l'Adapter afegim un nou atribut onItemClick al constructor:
class MyAdapter( private val dataList: List<String>, private val onItemClick: (Int) -> Unit ) : RecyclerView.Adapter<MyViewHolder>() { override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.itemView.setOnClickListener { onItemClick(position) } } }
A la instanciació de l'Adapter dins la Activity afegim la funció lambda que ens retorna la position del l'element clicat:
val adapter = MyAdapter(dataList) { position -> // Manejar el clic aquí Toast.makeText(this, "Clic: $position", Toast.LENGTH_SHORT).show() }