ListView: cos'è, elenchi semplici nelle applicazioni Android

Autore: IT Sectr Pubblicato: 2026-02-23 Tempo di lettura: 8 min

ListView è un componente Android di base per visualizzare elenchi verticali, disponibile dall'API 1 (Android 1.0). ListView crea un elenco di elementi utilizzando ArrayAdapter e supporta layout di cella personalizzati. Scopriamo cos'è ListView, come configurarlo e quali insidie nasconde questo componente vecchio ma ancora utilizzato. In IT Sectr incontriamo ListView in progetti legacy e manteniamo la compatibilità con Android 4.4. Per un confronto con l'alternativa moderna, leggi l'articolo su RecyclerView.

Punti chiave

  • ListView è un componente integrato dell'Android SDK per elenchi verticali, introdotto in Android 1.0.
  • ArrayAdapter è un adattatore standard per associare un array di dati a ListView tramite toString() o un layout personalizzato.
  • SimpleAdapter è un adattatore per elenchi da dati Map, comodo per schermate semplici senza ViewModel.
  • onItemClickListener è un gestore di clic integrato che non richiede implementazione aggiuntiva nell'adattatore.
  • convertView è un meccanismo di riutilizzo delle View in ListView che lo sviluppatore deve implementare manualmente (simile a ViewHolder).

Cos'è ListView in Android?

ListView è un ViewGroup del pacchetto android.widget, progettato per visualizzare un elenco scorrevole di elementi. ListView implementa il pattern AdapterView: i dati vengono passati tramite un adattatore (Adapter), che converte gli elementi di dati in Views visualizzate sullo schermo. ListView esiste nell'SDK Android dalla prima versione (API 1) e non richiede librerie aggiuntive.

L'architettura di ListView è più semplice di RecyclerView: LayoutManager è integrato (solo scorrimento verticale), le animazioni di modifica sono assenti, i divisori vengono impostati tramite l'attributo XML android:divider. ListView aggiunge automaticamente OverScrollView e l'evidenziazione del focus, semplificando la prototipazione. Secondo Statista (2025), circa il 15% delle app Android nella top 100 del Play Store contiene ancora ListView — per lo più progetti legacy con supporto minimo.

Storia e rilevanza

ListView è stato il componente principale per gli elenchi in Android dal 2008 al 2014, quando RecyclerView è stato presentato al Google I/O 2014. Nonostante sia parzialmente deprecato (soft-deprecated), ListView rimane disponibile in tutte le versioni di Android e non è marcato come @Deprecated nell'SDK API 35. Se il tuo progetto supporta Android 4.4 (API 19) e versioni precedenti, ListView è l'unica scelta integrata poiché RecyclerView richiede AndroidX e dipendenze Gradle.

Tipi di adattatori: ArrayAdapter e SimpleAdapter

ArrayAdapter è l'adattatore più popolare per ListView. Prende una List<T> e un layout per ogni elemento. Per impostazione predefinita, ArrayAdapter chiama toString() su ogni oggetto e visualizza il testo in simple_list_item_1 (un singolo TextView). Per la visualizzazione personalizzata, è necessario sovrascrivere getView() o passare un layout personalizzato al costruttore.

kotlin
// ListView con ArrayAdapter (testo semplice)
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val countries = listOf(
        "Russia", "USA", "Germania",
        "Francia", "Giappone", "Cina", "Brasile"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val adapter = ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            countries
        )
        binding.listView.adapter = adapter

        // Gestione clic
        binding.listView.onItemClickListener =
            AdapterView.OnItemClickListener { _, _, position, _ ->
                Toast.makeText(this, countries[position], Toast.LENGTH_SHORT).show()
            }
    }
}

SimpleAdapter è progettato per elenchi da dati Map. Prende una List<Map<String, Any>> e un array from/to per associare le chiavi Map agli ID dei widget nel layout. SimpleAdapter è comodo per prototipi rapidi quando non è necessaria una classe adattatore separata. Lo svantaggio è la mancanza di tipizzazione sicura e la complessità con la logica personalizzata.

xml
<!-- Layout con ListView -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/divider"
        android:dividerHeight="1px"
        android:scrollbars="vertical" />
</LinearLayout>

Creazione di un adattatore personalizzato con ViewHolder

L'adattatore personalizzato per ListView sovrascrive il metodo getView(), che RecyclerView divide in onCreateViewHolder + onBindViewHolder. In ListView, entrambi i passaggi sono combinati, quindi lo sviluppatore deve implementare indipendentemente il pattern ViewHolder tramite convertView (View riutilizzabile) e il metodo setTag().

kotlin
// Modello dati
data class Product(
    name: String,
    price: String,
    imageResId: Int
)

// Adattatore personalizzato con ViewHolder
class ProductAdapter(
    context: Context,
    private val products: List<Product>
) : ArrayAdapter<Product>(context, 0, products) {

    // ViewHolder per caching
    private class ViewHolder(view: View) {
        val nameText: TextView = view.findViewById(R.id.tvName)
        val priceText: TextView = view.findViewById(R.id.tvPrice)
        val imageView: ImageView = view.findViewById(R.id.ivProduct)
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val view = convertView ?: LayoutInflater.from(context)
            .inflate(R.layout.item_product, parent, false)
            .also { it.tag = ViewHolder(it) }

        val holder = view.tag as ViewHolder
        val product = getItem(position)

        holder.nameText.text = product.name
        holder.priceText.text = product.price
        holder.imageView.setImageResource(product.imageResId)

        return view
    }
}

Differenza principale da RecyclerView: in ListView, il metodo getView() viene chiamato ogni volta che un elemento appare sullo schermo. Se convertView e ViewHolder non vengono utilizzati, ogni scorrimento crea un nuovo oggetto View, causando perdite di memoria e rallentamenti su elenchi di oltre 50 elementi. ViewHolder con view.tag è un'ottimizzazione obbligatoria per ListView con layout personalizzati.

Limitazioni di ListView: perché Google raccomanda RecyclerView

ListView ha quattro limitazioni architetturali che Google ha risolto in RecyclerView: (1) solo orientamento verticale — niente griglie, elenchi orizzontali o a cascata; (2) nessuna notifica granulare — qualsiasi modifica dei dati attiva un ridisegno completo tramite notifyDataSetChanged(), causando tremolii; (3) nessuna animazione integrata di aggiunta/rimozione elementi; (4) nessuna separazione delle responsabilità — LayoutManager è integrato, ItemAnimator è assente.

xml
<!-- item_product.xml — layout elemento ListView -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="12dp">

    <ImageView
        android:id="@+id/ivProduct"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:scaleType="centerCrop" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:paddingStart="12dp">

        <TextView
            android:id="@+id/tvName"
            android:textSize="16sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tvPrice"
            android:textSize="14sp"
            android:textColor="@color/price" />
    </LinearLayout>
</LinearLayout>

Implicazioni pratiche: su elenchi fino a 20 elementi, ListView funziona veloce quanto RecyclerView. Con oltre 100 elementi, la differenza diventa evidente: ListView inizia a perdere FPS a causa della mancanza di calcoli diff e del ViewHolder forzato. Per elenchi con aggiornamenti frequenti (chat, feed, log), ListView non è adatto — usa RecyclerView con Paging 3. In IT Sectr, migriamo ListView a RecyclerView ogni volta che lavoriamo su schermate legacy con più di 50 elementi.

Configurazione di ListView tramite attributi XML

ListView fornisce un insieme di attributi XML per una configurazione rapida senza codice: android:divider (colore/drawable del divisore), android:dividerHeight (spessore), android:scrollbars (barre di scorrimento), android:fastScrollEnabled (scorrimento rapido tramite maniglia), android:choiceMode (modalità di selezione: singleChoice, multipleChoice). L'attributo android:entries consente di popolare l'elenco da un array di risorse (string-array) senza adattatore.

AttributoDescrizioneValore di esempio
android:dividerColore o drawable del divisore@color/gray_light
android:dividerHeightSpessore del divisore in px/dp1dp
android:entriesArray di stringhe dalle risorse@array/countries
android:choiceModeModalità di selezione elementosingleChoice
android:fastScrollEnabledScorrimento rapidotrue
android:overlapAnchorAncora per elenchi a comparsa (API 21+)true

Modalità di selezione: choiceMode="singleChoice" attiva lo stile RadioButton in cui l'elemento selezionato viene evidenziato. choiceMode="multipleChoice" — caselle di controllo per più elementi. I dati di selezione sono disponibili tramite listView.checkedItemPosition o listView.checkedItemIds. Importante: con choiceMode, ListView usa StateListDrawable per lo sfondo — imposta il tuo selettore se il blu standard non corrisponde al design.

ListView vs RecyclerView: confronto delle funzionalità

La scelta tra ListView e RecyclerView dipende dai requisiti del progetto. RecyclerView è lo standard moderno, ma ListView può essere giustificato per schermate semplici con costi di manutenzione minimi per codice legacy. Confronto su tutti i parametri chiave:

ParametroListViewRecyclerView
Dimensione libreriaIntegrato nell'SDK (≈60 KB)AndroidX (≈300 KB con dipendenze)
Versione minimaAPI 1API 14 (tramite AndroidX)
OrientamentoSolo verticaleVerticale, orizzontale, griglia, a cascata
ViewHolderImplementazione manualeObbligatorio per architettura
AnimazioneSolo transizioni dissolvenzaDefaultItemAnimator (add, remove, move, change)
Aggiornamenti granulariNo (solo notifyDataSetChanged)notifyItemInserted/Removed/Changed
Listener cliconItemClickListener (integrato)Tramite ViewHolder (non integrato)
PrestazioniSufficiente per elenchi fino a 50 elementi60 FPS stabili per oltre 1000 elementi

Conclusione: per i nuovi progetti, usa RecyclerView. Lascia ListView solo nel codice legacy dove la migrazione è irragionevolmente costosa. Secondo le linee guida di Material Design 3 (2026), gli elenchi di qualsiasi complessità dovrebbero usare RecyclerView per soddisfare gli standard moderni di prestazioni e accessibilità.

Domande frequenti

ListView è deprecato o no?

ListView non è marcato come @Deprecated nell'SDK Android API 35, ma Google non ne raccomanda l'uso nei nuovi progetti (soft-deprecated). Il componente rimane funzionante in tutte le versioni di Android. RecyclerView è la sostituzione ufficiale dal 2014. Se stai iniziando un nuovo progetto — scegli RecyclerView. Se stai mantenendo un progetto esistente — ListView continuerà a funzionare senza modifiche.

Come aggiungere header/footer a ListView?

ListView supporta i metodi addHeaderView(View, Object, boolean) e addFooterView(View, Object, boolean). Header e footer vengono aggiunti all'elenco generale degli elementi ma non partecipano all'adattatore — vengono sempre visualizzati all'inizio e alla fine dell'elenco. Importante: aggiungi header/footer prima di impostare l'adattatore (setAdapter()), altrimenti non verranno inclusi. Dopo aver aggiunto un header, gli ID di posizione degli elementi vengono spostati del numero di header.

Perché ListView non scorre all'interno di ScrollView?

Sia ListView che ScrollView gestiscono i gesti verticali, creando un conflitto: lo ScrollView esterno intercetta lo scorrimento e ListView non scorre. Soluzioni: (1) non annidare ListView in ScrollView — usa RecyclerView con NestedScrollingChild, (2) sostituisci ScrollView con NestedScrollView (API 21+), (3) usa ListView con altezza fissa (android:layout_height="...dp") all'interno di ScrollView, ma questo romperà l'adattabilità.

Come pulire ListView e aggiornare i dati?

La pulizia dei dati in ListView dipende dal tipo di adattatore. Per ArrayAdapter: adapter.clear() e adapter.addAll(newList) seguiti da adapter.notifyDataSetChanged(). Per adattatore personalizzato: aggiorna l'elenco dati e chiama notifyDataSetChanged(). Nota: listView.invalidateViews() ridisegna solo le View ma non aggiorna i dati. Modifica sempre i dati tramite l'adattatore, non direttamente.

Come cambiare l'altezza di un elemento ListView?

L'altezza di un elemento ListView viene impostata nel layout dell'elemento. Se il layout usa layout_height="wrap_content", l'altezza si adatta al contenuto. Per un'altezza fissa per tutti gli elementi, usa un adattatore personalizzato che imposta LayoutParams in getView(): view.layoutParams.height = resources.getDimensionPixelSize(R.dimen.itemHeight). Per altezze variabili, usa RecyclerView con diversi tipi di vista.

Riepilogo

  • ListView è un componente di base dell'Android SDK per elenchi verticali, disponibile dall'API 1.
  • ArrayAdapter è l'adattatore più semplice per un elenco di stringhe; per layout personalizzati serve un getView() sovrascritto.
  • ViewHolder in ListView viene implementato manualmente tramite convertView e view.tag — un requisito di prestazioni obbligatorio.
  • ListView supporta choiceMode (single/multiple), header/footer, fastScroll e android:entries senza adattatore.
  • Limitazioni di ListView: solo orientamento verticale, nessuna animazione, ridisegno completo a ogni modifica.
  • ListView non è marcato come deprecato, ma Google raccomanda RecyclerView per tutti i nuovi progetti.
  • Per elenchi fino a 50 elementi, ListView è sufficiente; per qualsiasi cosa più complessa — usa RecyclerView.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche