Crea elenchi dinamici con RecyclerView Componente di Android Jetpack.

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

RecyclerView consente di visualizzare facilmente grandi set di dati in modo efficiente. 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 dallo schermo, RecyclerView non ne distrugge la visualizzazione. Invece, RecyclerView riutilizza la visualizzazione per i nuovi elementi che hanno fatto scorrere lo schermo. RecyclerView migliora le prestazioni e la reattività della tua app, oltre a ridurre il consumo di energia.

Classi chiave

Diverse classi lavorano insieme per creare il tuo elenco dinamico.

  • RecyclerView è la ViewGroup che contiene le viste corrispondenti ai tuoi dati. È una visualizzazione stessa, quindi aggiungi RecyclerView al layout nello stesso modo in cui aggiungeresti qualsiasi altro elemento dell'interfaccia utente.

  • Ogni singolo elemento dell'elenco viene definito da un oggetto view holder. Una volta creato, il titolare della vista non ha dati associati. Una volta creato il titolare della visualizzazione, RecyclerView lo associa ai suoi dati. Puoi definire il titolare della visualizzazione estendendo RecyclerView.ViewHolder.

  • L'elemento RecyclerView richiede viste e associa le viste ai relativi dati, chiamando i metodi nell'adattatore. Puoi definire l'adattatore estendendo RecyclerView.Adapter.

  • Il gestore del layout dispone i singoli elementi nell'elenco. Puoi utilizzare uno dei gestori di layout forniti dalla libreria RecyclerView oppure puoi definirne uno personalizzato. I gestori del layout si basano tutti sulla classe astratta LayoutManager della libreria.

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

Passaggi per l'implementazione di RecyclerView

Se intendi utilizzare RecyclerView, devi eseguire alcune operazioni, spiegate dettagliatamente nelle sezioni seguenti.

  1. Decidi l'aspetto dell'elenco o della griglia. In genere, 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, estendi la classe ViewHolder. La tua versione di ViewHolder fornisce tutte le funzionalità per gli elementi dell'elenco. Il titolare della visualizzazione è un wrapper attorno a un View, e questa visualizzazione è gestita da RecyclerView.

  3. Definisci il valore Adapter che associa i dati alle viste ViewHolder.

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

Pianifica il layout

Gli elementi in RecyclerView sono organizzati da una classe LayoutManager. La libreria RecyclerView mette a disposizione tre gestori di layout, che gestiscono le situazioni di layout più comuni:

  • LinearLayoutManager organizza gli elementi in un elenco unidimensionale.
  • GridLayoutManager organizza gli elementi in una griglia bidimensionale:
    • Se la griglia è disposta verticalmente, GridLayoutManager cerca di far sì 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 far sì che tutti gli elementi in ogni colonna abbiano la stessa larghezza e altezza, ma colonne diverse possono avere larghezze diverse.
  • StaggeredGridLayoutManager è simile a GridLayoutManager, 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 colonna possono avere uno spostamento l'uno dall'altro.

Devi anche progettare il layout dei singoli elementi. Questo layout ti serve durante la progettazione del titolare della visualizzazione, come descritto nella sezione successiva.

Implementa l'adattatore e il supporto per visori

Una volta stabilito il layout, devi implementare Adapter e ViewHolder. Queste due classi lavorano insieme per definire le modalità di visualizzazione dei dati. ViewHolder è un wrapper attorno a un View che contiene il layout per un singolo elemento nell'elenco. L'elemento 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 principali:

  • onCreateViewHolder(): RecyclerView chiama questo metodo ogni volta che è necessario creare un nuovo ViewHolder. Il metodo crea e inizializza l'elemento ViewHolder e il relativo View, ma non compila i contenuti della visualizzazione perché l'elemento ViewHolder non è stato ancora 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 titolare della visualizzazione. Ad esempio, se RecyclerView mostra un elenco di nomi, il metodo potrebbe trovare il nome appropriato nell'elenco e compilare il widget TextView del proprietario 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 utilizza questo metodo per determinare quando non sono disponibili altri elementi che possono essere visualizzati.

Ecco un esempio tipico di adattatore semplice con ViewHolder nidificato che mostra un elenco di dati. In questo caso, RecyclerView mostra un semplice elenco di elementi di testo. All'adattatore viene trasmesso un array di stringhe contenente il testo degli 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 vista 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.adapter = customAdapter

    }

}

Java


RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(customAdapter);

che offre anche molti modi per personalizzare l'implementazione. Per ulteriori informazioni, consulta la sezione Personalizzazione avanzata di RecyclerView.

Risorse aggiuntive

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

App di esempio