RecyclerView Android Java – Guida Completa con Esempi

Guida completa a RecyclerView in Android (Java)

In questa guida vedremo innanzitutto in dettaglio come utilizzare RecyclerView in Android con Java: RecyclerView Android Java è una delle componenti fondamentali per visualizzare liste efficienti. Scopriremo cos’è, in cosa differisce da ListView, come configurarlo in un progetto, come creare l’adapter con ViewHolder, gestire i click sugli elementi e, infine, aggiungere/rimuovere elementi dinamicamente.

RecyclerView Android Java - diagramma architettura con Adapter e ViewHolder

Cos’è RecyclerView e le differenze con ListView

RecyclerView è un widget introdotto con la libreria AndroidX che permette di visualizzare liste e griglie di elementi in modo efficiente e flessibile. Inoltre, è l’evoluzione di ListView e GridView, con molte funzionalità in più e una gestione delle performance migliorata. Quando impari RecyclerView Android Java, scopri che questo componente è diventato lo standard de facto per lo sviluppo di app Android moderne.

In particolare, ecco le principali differenze tra RecyclerView e ListView:

  • ViewHolder obbligatorio: in RecyclerView il pattern ViewHolder è parte integrante dell’API, riduce le findViewById e migliora le performance.
  • LayoutManager: RecyclerView delega la disposizione degli elementi a un LayoutManager (lineare, a griglia, a pagine, personalizzato).
  • Animazioni: fornisce di default supporto migliore per animazioni di inserimento, rimozione e aggiornamento.
  • Altamente estensibile: supporta facilmente swipe, drag & drop, decorazioni personalizzate (divider, spazi, ecc.).
  • Maggiore controllo: nessun gestore di click integrato, sei tu a decidere come gestire gli eventi (tramite l’adapter o l’activity/fragment).

Dipendenze Gradle per RecyclerView Android

Per usare RecyclerView devi anzitutto aggiungere la dipendenza corrispondente nel file build.gradle del modulo app. Con AndroidX, in molti casi, è già inclusa tramite androidx.recyclerview:recyclerview. Ad esempio:

dependencies {
    // Altre dipendenze...

    implementation 'androidx.recyclerview:recyclerview:1.3.2'
}

Successivamente, dopo aver aggiunto la dipendenza, sincronizza il progetto (Sync Now) in Android Studio.

Creazione del layout XML per il singolo item in RecyclerView

Per prima cosa creiamo un layout XML che rappresenti il singolo elemento della lista (ad esempio un semplice testo con un sottotitolo). A tal proposito, crea un file item_persona.xml nella cartella res/layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp">

    <TextView
        android:id="@+id/textNome"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Nome"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <TextView
        android:id="@+id/textDettagli"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Dettagli"
        android:textSize="14sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textNome"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Layout dell’Activity con RecyclerView in Android

Ora creiamo il layout dell’activity che conterrà il RecyclerView, ad esempio activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewPersone"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Modello dati Java per gli elementi della RecyclerView

Quindi creiamo una semplice classe Java che rappresenti i dati di ogni riga del RecyclerView, ad esempio una persona:

public class Persona {

    private String nome;
    private String dettagli;

    public Persona(String nome, String dettagli) {
        this.nome = nome;
        this.dettagli = dettagli;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getDettagli() {
        return dettagli;
    }

    public void setDettagli(String dettagli) {
        this.dettagli = dettagli;
    }
}

Implementazione dell’Adapter con ViewHolder

L’Adapter è la classe che collega i dati alla vista. In particolare, con RecyclerView dobbiamo definire una classe che estende RecyclerView.Adapter<ViewHolder> e un ViewHolder interno che mantiene i riferimenti alle view del singolo item.

public class PersonaAdapter extends RecyclerView.Adapter<PersonaAdapter.PersonaViewHolder> {

    private List<Persona> listaPersone;
    private OnItemClickListener listener;

    // Interfaccia per gestire i click sugli item
    public interface OnItemClickListener {
        void onItemClick(Persona persona, int position);
    }

    public PersonaAdapter(List<Persona> listaPersone, OnItemClickListener listener) {
        this.listaPersone = listaPersone;
        this.listener = listener;
    }

    // ViewHolder: tiene i riferimenti alle view dell'item
    public static class PersonaViewHolder extends RecyclerView.ViewHolder {

        TextView textNome;
        TextView textDettagli;

        public PersonaViewHolder(@NonNull View itemView) {
            super(itemView);
            textNome = itemView.findViewById(R.id.textNome);
            textDettagli = itemView.findViewById(R.id.textDettagli);
        }

        public void bind(final Persona persona, final OnItemClickListener listener, final int position) {
            textNome.setText(persona.getNome());
            textDettagli.setText(persona.getDettagli());

            // Gestione click sull'intero item
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listener != null) {
                        listener.onItemClick(persona, position);
                    }
                }
            });
        }
    }

    @NonNull
    @Override
    public PersonaViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // Infliamo il layout del singolo item
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_persona, parent, false);
        return new PersonaViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull PersonaViewHolder holder, int position) {
        // Recuperiamo l'elemento alla posizione indicata
        Persona persona = listaPersone.get(position);
        // Bind dei dati alla view
        holder.bind(persona, listener, position);
    }

    @Override
    public int getItemCount() {
        return listaPersone.size();
    }

    // Metodi di utilitá per aggiungere/rimuovere elementi dinamicamente

    public void aggiungiPersona(Persona persona) {
        listaPersone.add(persona);
        // Notifica RecyclerView che un elemento è stato inserito alla fine
        notifyItemInserted(listaPersone.size() - 1);
    }

    public void rimuoviPersona(int position) {
        if (position >= 0 && position < listaPersone.size()) {
            listaPersone.remove(position);
            // Notifica la rimozione di un elemento
            notifyItemRemoved(position);
        }
    }
}

Nell’adapter abbiamo anche definito metodi per aggiungere e rimuovere elementi, che, in questo modo, utilizzeremo più avanti.

Collegamento di RecyclerView nell’Activity (LinearLayoutManager)

Ora colleghiamo tutto dentro la nostra MainActivity. Pertanto useremo un LinearLayoutManager per mostrare gli elementi in una lista verticale.

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerViewPersone;
    private PersonaAdapter adapter;
    private List<Persona> listaPersone;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Inizializziamo la lista di dati
        listaPersone = new ArrayList<>();
        listaPersone.add(new Persona("Mario Rossi", "Sviluppatore Android"));
        listaPersone.add(new Persona("Luca Bianchi", "Designer UI/UX"));
        listaPersone.add(new Persona("Anna Verdi", "Project Manager"));

        // Recuperiamo il RecyclerView dal layout
        recyclerViewPersone = findViewById(R.id.recyclerViewPersone);

        // Migliora le performance se la dimensione non cambia
        recyclerViewPersone.setHasFixedSize(true);

        // Impostiamo un LayoutManager lineare (lista verticale)
        RecyclerView.LayoutManager layoutManager =
                new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerViewPersone.setLayoutManager(layoutManager);

        // Creiamo l'adapter passando lista e listener per i click
        adapter = new PersonaAdapter(listaPersone, new PersonaAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(Persona persona, int position) {
                // Azione da eseguire al click: ad esempio mostrare un Toast
                Toast.makeText(MainActivity.this,
                        "Hai cliccato: " + persona.getNome(),
                        Toast.LENGTH_SHORT).show();
            }
        });

        // Colleghiamo l'adapter al RecyclerView
        recyclerViewPersone.setAdapter(adapter);
    }
}

Utilizzo di GridLayoutManager per una griglia

Se vuoi mostrare gli elementi in forma di griglia (ad esempio immagini o card), puoi utilizzare GridLayoutManager al posto di LinearLayoutManager; in questo modo otterrai una visualizzazione a colonne.

// Esempio di utilizzo di GridLayoutManager con 2 colonne
RecyclerView.LayoutManager gridLayoutManager =
        new GridLayoutManager(this, 2, RecyclerView.VERTICAL, false);
recyclerViewPersone.setLayoutManager(gridLayoutManager);

In questo modo, 2 indica il numero di colonne. Puoi modificarlo a seconda delle tue esigenze e dell’ampiezza dello schermo.

Gestione dei click sugli item in RecyclerView Android

Nel nostro esempio abbiamo scelto di gestire i click tramite una interfaccia OnItemClickListener definita nell’adapter e, in questo modo, teniamo separata la logica di visualizzazione dalla logica di interazione.

Ricorda che, a differenza di ListView, RecyclerView non ha un metodo setOnItemClickListener integrato: pertanto è tua responsabilità implementare la gestione degli eventi (come abbiamo fatto nel metodo bind() del ViewHolder).

Se vuoi gestire il click su un singolo elemento della riga (ad esempio un bottone), puoi, ad esempio, aggiungere un OnClickListener direttamente a quella view nel ViewHolder.

// Esempio (all'interno del ViewHolder)
Button buttonAzione = itemView.findViewById(R.id.buttonAzione);
buttonAzione.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Azione specifica per il bottone di questo item
    }
});

Aggiunta dinamica di elementi in RecyclerView Android Java

Grazie ai metodi di utilità nell’adapter, possiamo aggiungere dinamicamente nuove persone alla lista. Ad esempio, in MainActivity potremmo avere un bottone che, quando cliccato, aggiunge un nuovo elemento e, in questo modo, aggiorna la lista.

Button buttonAggiungi = findViewById(R.id.buttonAggiungi);
buttonAggiungi.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Persona nuovaPersona = new Persona("Nuova Persona", "Aggiunta dinamicamente");
        adapter.aggiungiPersona(nuovaPersona);
    }
});

All’interno del metodo aggiungiPersona() dell’adapter abbiamo già incluso la chiamata a notifyItemInserted(), che informa il RecyclerView della nuova voce e permette di mostrare automaticamente, di conseguenza, eventuali animazioni di inserimento.

Rimozione dinamica di elementi dalla RecyclerView Android

In modo analogo, possiamo rimuovere elementi dinamicamente. Ad esempio, potremmo rimuovere l’elemento cliccato; in questo modo manteniamo la lista sempre aggiornata.

adapter = new PersonaAdapter(listaPersone, new PersonaAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(Persona persona, int position) {
        // Rimuove l'elemento cliccato
        adapter.rimuoviPersona(position);
    }
});

Il metodo rimuoviPersona() dell’adapter chiama notifyItemRemoved(position), pertanto il RecyclerView aggiorna la lista e può visualizzare l’animazione di rimozione.

Riepilogo finale su RecyclerView Android Java

In questa guida su RecyclerView Android Java abbiamo visto come:

  • aggiungere la dipendenza Gradle per RecyclerView;
  • creare il layout XML per il singolo item e per l’activity con RecyclerView;
  • definire un modello dati (classe Persona);
  • implementare un adapter con ViewHolder e un listener per i click;
  • collegare RecyclerView nell’activity usando LinearLayoutManager;
  • passare a una disposizione a griglia con GridLayoutManager;
  • aggiungere e rimuovere dinamicamente elementi dalla lista.

Partendo da qui puoi, infine, espandere il tuo RecyclerView con layout più complessi, immagini, swipe per eliminare elementi, drag & drop per riordinare la lista e molto altro.

Guide correlate su Android Java

Commenti

Rispondi

Scopri di più da App Tutorial

Abbonati ora per continuare a leggere e avere accesso all'archivio completo.

Continua a leggere