Understanding Android: ListView, Progettazione e Ottimizzazione

Diego Stamigni
Diego Stamigni
Understanding Android: ListView, Progettazione e Ottimizzazione

Buonasera signori,

che ne dite di una serata all'insegna del Coding? Torna l'Understanding Android, più forte che mai. Questo corso si occupa di chiarire alcuni aspetti importanti nella programmazione Android, che molte volte vengono tralasciati. Oggi andremo toccando con mano uno di questi aspetti: le ListView.

Perchè un intero articolo sulle ListView? Principalmente perchè sono molto usate e in seconda misura perchè vengono programmate in modo non ottimizzato e questo non è accettabile. Ho visto troppi pezzi di codice errati, errati nel senso che gli algoritmi di implementazione dei dati nelle liste venivano fatti di continuo, senza tener conto di alcuni passaggi fondamentali, che altresì avrebbero prodotto un qualcosa di efficente. Ingegneria del software.

Gli argomenti trattati saranno di un livello med-advanced, se conoscete poco la programmazione Android, non preoccupatevi se capirete poco, è normale, ma abbiate cura di leggere ad ogni modo l'articolo, così da avere almeno una idea di come bisogna comportarsi in alcuni aspetti. Ci tengo a ripetere che in questo caso particolare, si sta facendo una precisazione su COME andrebbero usate le ListView.

Cosa sono le ListView? Semplicemente una lista di elementi, scrollabile, dinamica, ma abbastanza complessa nella sua semplicità.

Cominciamo con il dire che le ListView sono associate a ListAdapter, che provengono da Adapter, come estensione. Tutto ciò appartiene al package android.widget, e in forma gerarchica l'Adapter si presenta come interfaccia, così come le ListAdapter. L'Adapter è un componente che si occupa di adattare la sorgente dei dati da un componente responsabile della loro visualizzazione.

Cerchiamo di venire al punto; ce ne sarebbe da parlare ancora per molto, ma il titolo di quest'articolo è ListView, Progettazione e Ottimizzazione.
Ipotizziamo di avere dei dati, come possono essere ad esempio la lista dei contatti telefonici detta comunemente rubrica. Come effettuare correttamente un riempimento nella ListView cercando di risparmiare risorse e battiture inutili su tastiera? Semplice, in due modi che andremo adesso ad esplicare.

Il primo metodo è il cosidetto inflating. Quest'ultimo è una particolare opportunità di trasformare il documento di un layout XML nella struttura di una View.

Ora, ammettiamo di avere un layout main.xml dove abbiamo la nostra ListView e un altro XML in cui abbiamo due TextView, nome e cognome (prendiamo come esempio la rubrica telefonica, come già detto). Tre cose, ListView, due TextView. Quanti elementi avrà la nostra rubrica? Non lo so, non mi è dato a saperlo, io ho tre elementi.

Attraverso l'inflating, su eventi particolari, posso crearmi un metodo che riempia la ListView e associ alle TextView rispettivamente nome e cognome. Ma come fare al meglio tutto ciò?

Come vedete nel codice sopra, questo è il metodo più scorretto che possa esistere: in date.xml abbiamo le nostre TextView firstname e lastname. L'Inflating è corretto, ma non ottimizzato. L'inflate è un'operazione pesante, potete ben capire perchè; è pertanto NECESSARIO limitarne l'uso. Nel metodo sopra visualizzato non viene fatto nessun controllo riguardo alla possibilità che ci sia già stato un inflating, conseguentemente  se ci fosse già stato, verrebbe comunque rifatto da zero.

Inaccettabile.

Introduciamo però un altro elemento nel nostro costruttore che effettua esattamente questo controllo:

Bene, il nuovo parametro è convertView sul quale viene effettuato un test: se è null viene fatto l'intero inflating, altrimenti viene sfruttato quello già presente, semplicemente riassegnando i valori corrispondenti alle TextView.

E' possibile sfruttare il metodo semplicemente passandolo a getView() sotto @Overriding.

Un altro ottimo metodo per procedere è utilizzando una SimpleAdapter, rimuovendo l'inflating che continua a essere un problema su una grande mole di dati. Vediamola: come potete capire dal nome, SimpleAdapter è un'implementazione Semplice dell'Adapter contenuta nel package android.widget. Questa permette in modo rapido la creazione di implementazioni di Adapter nel caso in cui si avessero già a disposizione un insieme di dati nella forma di un ArrayList di Map. Qui non viene fatto un pesante inflating, ma si riempie un array:

Come vedete il codice è molto corto e non molto complesso: dobbiamo soddisfare il costruttore del SimpleAdapter: vuole il context (fin qui nessun problema), un riferimento alla struttura dati che è rappresentata da un'ArrayList di Map, una lista di List<? extends Map<String,?>> generata attraverso il metodo createItems() (ecco qui il nostro bel array dinamico che si riempie)), la risorsa (il nostro layout dove sono le textview), un'array String[] from (contenente le chiavi da utilizzare) e un array int[] to (contenente le relative View da associare).

Quello che andiamo a fare nel codice è proprio questo, in modo molto banale.

Assegniamo alla fine il tutto alla ListView e il gioco è fatto.

Tra i due modi di operare, c'è da considerare che nel primo viene effettuato un inflating (una volta, ma è comunque una procedura molto pesante), nel secondo un riempimento di un'ArrayList che è anch'esso una procedura abbastanza pesante se si parla di un'ampia mole di dati.

Per ora credo che possiamo chiuderla qui, ho espresso molti concetti in modo veloce, ma come sapete, vi aspetto sul forum, precisamente nella sezione Guide dove potete chiedermi tutto ciò che volete a riguardo nell'apposito thread.

Se avete richieste particolari su argomenti che volete che tratti, chiedete nei commenti o nel forum.

Happy hacking.