Crea elenchi dinamici con RecyclerView   Componente di Android Jetpack.

Prova la funzionalità Scrivi
Jetpack Compose è il toolkit per l'interfaccia utente consigliato per Android. Scopri come utilizzare i layout in Compose.

RecyclerView semplifica la visualizzazione efficiente di grandi set di dati. Fornisci i dati e definisci l'aspetto di ogni elemento, mentre la libreria RecyclerView crea dinamicamente gli elementi quando sono necessari.

Come suggerisce il nome, RecyclerView ricicla questi singoli elementi. Quando un elemento scompare dallo schermo, RecyclerView non ne distrugge la visualizzazione. Al contrario, RecyclerView riutilizza la visualizzazione per i nuovi elementi che sono stati visualizzati sullo schermo. RecyclerView migliora le prestazioni e la reattività della tua app e riduce il consumo energetico.

Classi principali

Diversi tipi di classi collaborano per creare l'elenco dinamico.

  • RecyclerView è l'ViewGroup contenente le visualizzazioni corrispondente ai tuoi dati. Poiché è una visualizzazione, aggiungi RecyclerView al layout come faresti con qualsiasi altro elemento dell'interfaccia utente.

  • Ogni singolo elemento dell'elenco è definito da un oggetto view holder. Quando viene creato, il contenitore della visualizzazione non ha dati associati. Dopo aver creato il visualizzatore, RecyclerView lo collega ai relativi dati. Puoi definire il visualizzatore estendendo RecyclerView.ViewHolder.

  • RecyclerView richiede le visualizzazioni e le associa ai relativi dati chiamando i metodi nell'adattatore. Definisci l'adattatore estendendo RecyclerView.Adapter.

  • Il gestore del layout organizza i singoli elementi dell'elenco. Puoi utilizzare uno dei gestori di layout forniti dalla libreria RecyclerView oppure definirne uno tuo. Tutti i gestori del layout si basano sulla classe astratta LayoutManager della raccolta.

Puoi vedere come si combinano tutti i componenti nell'app di esempio RecyclerView (Kotlin) o nell'app di esempio RecyclerView (Java).

Passaggi per implementare RecyclerView

Se vuoi utilizzare RecyclerView, devi fare alcune cose. Queste operazioni sono spiegate in dettaglio nelle sezioni seguenti.

  1. Decidi l'aspetto dell'elenco o della griglia. Di solito, puoi utilizzare uno dei gestori di layout standard della libreria RecyclerView.

  2. Progetta l'aspetto e il comportamento di ogni elemento dell'elenco. In base a questo design, espandi la classe ViewHolder. La tua versione di ViewHolder fornisce tutte le funzionalità per gli elementi dell'elenco. Il tuo contenitore della visualizzazione è un wrapper di un View e questa visualizzazione è gestita da RecyclerView.

  3. Definisci l'Adapter che associa i dati alle visualizzazioni ViewHolder.

Esistono anche opzioni di personalizzazione avanzata che ti consentono di personalizzare RecyclerView in base alle tue esigenze specifiche.

Pianifica il layout

Gli elementi di RecyclerView sono disposti in base a una LayoutManager classe. La libreria RecyclerView fornisce tre gestori di layout che gestiscono le situazioni di layout più comuni:

  • LinearLayoutManager ordina gli elementi in un elenco unidimensionale.
  • GridLayoutManager ordina gli elementi in una griglia bidimensionale:
    • Se la griglia è disposta in verticale, GridLayoutManager tenta di impostare la stessa larghezza e altezza per tutti gli elementi di ogni riga, ma le righe diverse possono avere altezze diverse.
    • Se la griglia è disposta orizzontalmente, GridLayoutManager tenta di impostare la stessa larghezza e altezza per tutti gli elementi di ogni colonna, ma le colonne diverse possono avere larghezze diverse.
  • StaggeredGridLayoutManager è simile a GridLayoutManager, ma non richiede che gli elementi di una riga abbiano la stessa altezza (per le griglie verticali) o che gli elementi della stessa colonna abbiano la stessa larghezza (per le griglie orizzontali). Di conseguenza, gli elementi in una riga o una colonna possono finire per essere sfalsati tra loro.

Devi anche progettare il layout dei singoli elementi. Questo layout è necessario quando progetti il contenitore della visualizzazione, come descritto nella sezione successiva.

Implementa l'adattatore e il supporto della visualizzazione

Una volta stabilito il layout, devi implementare Adapter e ViewHolder. Queste due classi lavorano insieme per definire il modo in cui vengono visualizzati i dati. ViewHolder è un wrapper di un View che contiene il layout di un singolo elemento nell'elenco. Adapter crea gli oggetti ViewHolder in base alle esigenze e imposta anche i dati per queste viste. Il processo di associazione delle visualizzazioni ai relativi dati è chiamato associazione.

Quando definisci l'adattatore, sostituisci tre metodi chiave:

  • onCreateViewHolder(): RecyclerView chiama questo metodo ogni volta che deve creare un nuovo ViewHolder. Il metodo crea e inizializza il ViewHolder e il relativo View associato, ma non compila i contenuti della visualizzazione: il ViewHolder non è ancora stato associato a dati specifici.

  • onBindViewHolder(): RecyclerView chiama questo metodo per associare un ViewHolder ai dati. Il metodo recupera i dati appropriati e li utilizza per compilare il layout del visualizzatore. Ad esempio, se RecyclerView mostra un elenco di nomi, il metodo potrebbe trovare il nome appropriato nell'elenco e compilare il widget TextView del detentore della visualizzazione.

  • getItemCount(): RecyclerView chiama questo metodo per ottenere le dimensioni del set di dati. Ad esempio, in un'app di rubrica potrebbe essere il numero totale di indirizzi. RecyclerView lo utilizza per determinare quando non sono più disponibili elementi da visualizzare.

Ecco un esempio tipico di un semplice adattatore con un ViewHolder nidificato che visualizza un elenco di dati. In questo caso, RecyclerView mostra un semplice elenco di elementi di testo. All'adattatore viene passato un array di stringhe contenente 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 della visualizzazione è definito in un file di layout XML, come di consueto. In questo caso, l'app ha un file text_row_item.xml come questo:

<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 maggiori informazioni, consulta la sezione Personalizzazione avanzata di RecyclerView.

Risorse aggiuntive

Per ulteriori informazioni sui test su Android, consulta le seguenti risorse.

App di esempio