Programmazione Avanzata: Lezione 1 – Programmazione Multischermo Android Blog Italia.
Dopo il successo del corso di programmazione per Android, a grande richiesta riprendiamo le lezioni introducendo concetti di programmazione avanzata. Inizieremo con uno degli argomenti più delicati per uno sviluppatore Android: la programmazione multischermo.
Introduzione
Non serve ricordare quanto il panorama Android sia frammentato, non solo per quanto riguarda le versioni del sistema operativo, ma anche per quanto riguarda i tipi di dispositivo (smartphone, tablet da 7 pollici, tablet da 10 pollici, addirittura TV) e le tipologie di schermi (hd, ultra hd, ecc..). Programmare un’applicazione per ognuno di questi dispositivi può diventare un inferno: il layout perfetto per uno smartphone può essere estremamente scomodo per un tablet, e un’immagine di media grandezza può essere visualizzata in maniera ottimale su uno schermo con bassa risoluzione ma diventare estremamente piccola in uno schermo ad alta definizione. Cerchiamo di capire come destreggiarci fra i vari dispositivi e schermi.
Schermi Multidimensioni
Iniziamo a vedere come gestire il layout per diversi tipi di schermo. Come sempre creiamo un nuovo progetto, e chiamiamolo “multischermo”. Per i più arrugginiti, ricordiamo la procedura: cliccate su File->New->AndroidApplicationProject. Seguite la procedura guidata fino al completamento della creazione. Attraverso il Package Explorer andiamo sulla cartella res del progetto, e cliccando col tasto destro del mouse andiamo su New->Folder. Creiamo così 2 nuove cartelle, una di nome layout-large e una di nome layout-xlarge.
Attenzione! Le cartelle devono avere esattamente gli stessi nomi, altrimenti Android non le riconoscerà, questo anche se Eclipse non vi segnala errori.Creiamo in ognuna di esse il file activity_main.xml (tasto destro del mouse, New->Android XML File. Il risultato alla fine dovrebbe essere questo:
Notare che i file XML hanno lo stesso nome, ma possono avere contenuti diversi. Il contenuto di layout/activity_main verrà usato per impostare il layout degli smartphone, quello di layout-large/activity_main sarà invece relativo ai tablet da 7 pollici e layout-xlarge/activity_main infine per quelli da 10 pollici. Prendiamo ora 3 immagini, smartphone, tablet 7, e tablet 10, e inseriamole nella cartella “drawable-hdpi” (ci soffermeremo presto sulla differenza tra queste cartelle).Tramite l’editor grafico inseriamo nei vari activity_main.xml una ImageView che ha come src rispettivamente l’url delle 3 immagini.
Avremo quindi un layout diverso (stessa ImageView ma con immagini diverse) per ogni cartella. Il risultato sarà quindi il seguente:
Questo significa che andando ad eseguire la stessa identica applicazione su dispositivi diversi, questa verrà visualizzata in maniera diversa.
Notate che non abbiamo modificato nemmeno una riga di codice Java! Layout e codice rimangono così indipendenti.Schermi con Differenti Risoluzioni
Spesso schermi con le stesse dimensioni (in pollici) hanno risoluzioni completamente diverse. La risoluzione degli schermi negli smartphone è spesso espressa in dpi ( dots per incs, “punti per pollice”).
Questo significa che una immagine di 100pixel x 100pixel su uno schermo con elevata densità verrà visualizzata più piccola rispetto alla stessa immagine su uno schermo con più basso numero di dpi. Infatti, essendo i pixel più “densi”, servirà uno spazio fisico minore per contenerli.
Ma se io volessi ottenere sempre la stessa grandezza, indipendentemente dalla risoluzione? Per questo ci viene in aiuto la definizione di dip ( density indipendent pixel ):
1 dip = 1 pixel su uno schermo a 160 dpi
Facendo qualche calcolo ci accorgiamo che 63 pixel a 160 dip (cioè 63 dip) sono uguali ad un 1 cm. Detto questo possiamo ragionare in 2 maniere:
- Prendiamo una ImageView, settiamo i campi “layout_width” e “layout_height” a 63 dip, prendendo come src la stessa immagine
- Prendiamo una ImageView ma definiamo una immagine specifica per ogni cartella (drawable-ldpi, drawable-mdpi, drawable-hdpi, ecc..).
Cerchiamo di capire cosa succede:
- Nel primo caso Android in modo automatico ridimensiona la mia immagine adattandola alla dimensione (1 cm ) che voglio, indipendentemente dalla grandezza dello schermo e/o della sua risoluzione
- Nel secondo caso a seconda della risoluzione dello schermo Android caricherà una immagine diversa (naturalmente l’immagine sarà ,in pixel, più grande man mano che la densità aumenta) prendendola dalla cartella corrispondente (vedi tabella alla fine).
Delle 2 soluzioni quella preferibile è la seconda, poichè con la prima potrebbe esserci perdità di qualità dovuta allo stretching” dell’immagine.
Quindi per avere una resa ottima dovremo, calcolatrice alla mano, calcolare quanti pixel dovrà essere grande ogni immagine da inserire in ogni cartella. Fortunatamente ci sono alcuni strumenti che vengono in aiuto a chi è negato in matematica.
Uno fra questi è Android Asset Studio:
Settando tutto correttamente (fra cui il campo “size” a 63 dip) otterremo uno zip contenente l’immagine data come input già ridimensionata adeguatamente e inserita nella cartella corrispondente. Basterà quindi copiare ciascuna immagine nella cartella apposita del progetto Android ed inserire nel proprio layout una ImageView (senza modificare i campi “layout_width” e “layout_height”), ottenendo un risultato simile ma graficamente migliore di quello ottenuto con il semplice ridimensionamento tramite dip.
Vi lasciamo con una tabella reperibile sul sito ufficiale Android che mostra la corrispondenza fra dpi e cartelle del progetto:
Poichè si tratta di argomenti e concetti non semplici da assimilare (e quindi ancora di più da spiegare) invito qualora ci fossero dubbi o cose poco chiare a scrivere come sempre nei commenti, tenterò di risponde nel migliore dei modi.
Programmazione Avanzata: Lezione 1 – Programmazione Multischermo Android Blog Italia.