Crea elenchi dinamici con RecyclerView Parte di Android Jetpack.
RecyclerView semplifica la visualizzazione efficiente di grandi set di dati. Tu fornisci i dati e definisci l'aspetto di ogni elemento e la libreria RecyclerView crea dinamicamente gli elementi quando sono necessari.
Come suggerisce il nome, RecyclerView ricicla i singoli elementi. Quando un elemento scorre fuori dalla schermata, RecyclerView non ne elimina la visualizzazione. RecyclerView riutilizza la visualizzazione per i nuovi elementi che hanno fatto scorrere la visualizzazione sullo schermo. RecyclerView migliora le prestazioni e la reattività della tua app e riduce il consumo energetico.
Classi chiave
Più corsi collaborano per creare il tuo elenco dinamico.
RecyclerView
è il parametroViewGroup
che contiene le viste corrispondenti ai tuoi dati. È una vista a sé stante, quindi aggiungiRecyclerView
al tuo layout come aggiungeresti qualsiasi altro elemento UI.Ogni singolo elemento dell'elenco è definito da un oggetto view holder. Quando viene creato il titolare della vista, non ha dati associati. Dopo la creazione del titolare della vista,
RecyclerView
lo associa ai suoi dati. Per definire il titolare della vista, puoi estendereRecyclerView.ViewHolder
.RecyclerView
richiede le viste e le associa ai relativi dati, chiamando i metodi nell'adattatore. Devi definire l'adattatore estendendoRecyclerView.Adapter
.Lo strumento di gestione del layout consente di organizzare i singoli elementi dell'elenco. Puoi utilizzare uno dei gestori del layout forniti dalla libreria RecyclerView oppure puoi definirne uno personalizzato. I gestori dei layout si basano tutti sul corso astratto
LayoutManager
della libreria.
Puoi vedere come tutti i pezzi si incastrano insieme nell'app di esempio RecyclerView (Kotlin) o nell'app di esempio RecyclerView (Java).
Passaggi per implementare RecyclerView
Se utilizzerai RecyclerView, ci sono alcune cose che devi fare, che sono spiegate dettagliatamente nelle sezioni seguenti.
Decidi l'aspetto dell'elenco o della griglia. In genere, puoi utilizzare uno dei gestori del layout standard della libreria RecyclerView.
Progetta l'aspetto e il comportamento di ogni elemento nell'elenco. In base a questo design, estendi la classe
ViewHolder
. La tua versione diViewHolder
fornisce tutte le funzionalità per gli elementi dell'elenco. Il titolare della vista è un wrapper attorno a unView
e questa vista è gestita daRecyclerView
.Definisci il valore
Adapter
che associa i tuoi dati alle visteViewHolder
.
Sono inoltre disponibili opzioni di personalizzazione avanzate che ti consentono di personalizzare la RecyclerView in base alle tue esigenze specifiche.
Pianifica il layout
Gli elementi in RecyclerView vengono ordinati per una classe LayoutManager
. La libreria RecyclerView offre tre gestori del layout, che gestiscono
le situazioni di layout più comuni:
LinearLayoutManager
dispone gli elementi in un elenco unidimensionale.GridLayoutManager
dispone gli elementi in una griglia bidimensionale:- Se la griglia è disposta verticalmente,
GridLayoutManager
cerca di fare in modo che tutti gli elementi in ogni riga abbiano la stessa larghezza e altezza, ma righe diverse possono avere altezze diverse. - Se la griglia è disposta orizzontalmente,
GridLayoutManager
cerca di fare in modo che tutti gli elementi in ogni colonna abbiano la stessa larghezza e altezza, ma colonne diverse possono avere larghezze diverse.
- Se la griglia è disposta verticalmente,
StaggeredGridLayoutManager
è simile aGridLayoutManager
, ma non richiede che gli elementi in una riga abbiano la stessa altezza (per le griglie verticali) o che gli elementi nella stessa colonna abbiano la stessa larghezza (per le griglie orizzontali). Il risultato è che gli elementi in una riga o in una colonna possono finire con uno sfalsamento l'uno dall'altro.
Devi anche progettare il layout dei singoli elementi. Hai bisogno di questo layout quando progetti il contenitore della vista, come descritto nella prossima sezione.
Implementare l'adattatore e il supporto della vista
Una volta stabilito il layout, devi implementare le Adapter
e
ViewHolder
. Queste due classi collaborano per definire la modalità di visualizzazione
dei dati. ViewHolder
è un wrapper attorno a una View
che contiene il layout per un singolo elemento dell'elenco. Adapter
crea oggetti ViewHolder
in base alle esigenze e imposta anche i dati per queste viste. Il processo di associazione delle viste ai relativi dati è chiamato associazione.
Quando definisci l'adattatore, esegui l'override di tre metodi chiave:
onCreateViewHolder()
:RecyclerView
chiama questo metodo ogni volta che deve creare un nuovoViewHolder
. Il metodo crea e inizializzaViewHolder
e il relativoView
associato, ma non riempie i contenuti della vista:ViewHolder
non è ancora stato associato a dati specifici.onBindViewHolder()
:RecyclerView
chiama questo metodo per associareViewHolder
ai dati. Il metodo recupera i dati appropriati e li utilizza per compilare il layout del titolare della vista. Ad esempio, seRecyclerView
mostra un elenco di nomi, il metodo potrebbe trovare il nome appropriato nell'elenco e compilare il widgetTextView
del titolare della vista.getItemCount()
:RecyclerView
chiama questo metodo per ottenere la dimensione del set di dati. Ad esempio, in un'app di rubrica, questo potrebbe essere il numero totale di indirizzi. RecyclerView utilizza questo metodo per determinare quando non ci sono altri elementi che possono essere visualizzati.
Ecco un esempio tipico di un adattatore semplice con un elemento ViewHolder
nidificato che
visualizza un elenco di dati. In questo caso, RecyclerView mostra un semplice
elenco di elementi di testo. All'adattatore viene trasmesso un array di stringhe contenenti il testo
per gli elementi ViewHolder
.
Kotlin
class CustomAdapter(private val dataSet: Array<String>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() { /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val textView: TextView init { // Define click listener for the ViewHolder's View textView = view.findViewById(R.id.textView) } } // Create new views (invoked by the layout manager) override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { // Create a new view, which defines the UI of the list item val view = LayoutInflater.from(viewGroup.context) .inflate(R.layout.text_row_item, viewGroup, false) return ViewHolder(view) } // Replace the contents of a view (invoked by the layout manager) override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.textView.text = dataSet[position] } // Return the size of your dataset (invoked by the layout manager) override fun getItemCount() = dataSet.size }
Java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private String[] localDataSet; /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; public ViewHolder(View view) { super(view); // Define click listener for the ViewHolder's View textView = (TextView) view.findViewById(R.id.textView); } public TextView getTextView() { return textView; } } /** * Initialize the dataset of the Adapter * * @param dataSet String[] containing the data to populate views to be used * by RecyclerView */ public CustomAdapter(String[] dataSet) { localDataSet = dataSet; } // Create new views (invoked by the layout manager) @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view, which defines the UI of the list item View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.text_row_item, viewGroup, false); return new ViewHolder(view); } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.getTextView().setText(localDataSet[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return localDataSet.length; } }
Il layout di ogni elemento di visualizzazione viene definito, come di consueto, in un file di layout XML.
In questo caso, l'app ha un file text_row_item.xml
simile al seguente:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/element_text"/>
</FrameLayout>
Passaggi successivi
Il seguente snippet di codice mostra come utilizzare RecyclerView
.
Kotlin
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val dataset = arrayOf("January", "February", "March") val customAdapter = CustomAdapter(dataset) val recyclerView: RecyclerView = findViewById(R.id.recycler_view) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = customAdapter } }
Java
RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.layoutManager = new LinearLayoutManager(this) recyclerView.setAdapter(customAdapter);
La libreria offre anche molti modi per personalizzare l'implementazione. Per ulteriori informazioni, consulta la Personalizzazione avanzata di RecyclerView.
Risorse aggiuntive
Per ulteriori informazioni sui test su Android, consulta le risorse che seguono.