20.000 risoluzioni sotto Android: adattiamo la grafica delle nostre applicazioni a tutti i display esistenti

Android puzzle

A differenza di uno sviluppatore iOS che sa esattamente su che tipo di device/schermo verrà usata la propria applicazione, lo sviluppatore Android ha talmente tanta scelta che può quasi sentirsi a disagio. Disagio perché le centiaia di modelli di telefoni Android in commercio hanno le risoluzioni e le dimensioni degli schermi più disparate. La soluzione è davvero riscrivere la nostra applicazione per ogni risoluzione come sostengono alcuni? Mamma Google non ci lascebbe MAI (o non gli conviene lasciarci?) con una incombenza di questo tipo: la frammentazione del mondo Android infatti in questo caso risente dei suoi limiti, ma ovviamente una soluzione c’è! Cerchiamo quindi di pensare in proporzionale: abbandoniamo il “pixel” (px) e abbracciamo il “density-independent pixel” (dp)!

Risoluzioni e densità

La risoluzione standard per i telefoni attualmente in commercio è HVGA, cioè Half-size Video Grafic Array, che in numeri fa 320 x 480 pixel. Per intendersi, è quella che ha anche iPhone pre-retina display. Se si ragiona in assoluto però come si fa con iPhone, si rischia di sballare tutte le proporzioni degli elementi della nostra interfaccia su risoluzioni differenti.

Risoluzioni comuni in Android

Per semplificare le cose, gli sviluppatori Android hanno raggruppato le dimensioni degli schermi in una griglia in base alle combinazioni tra risoluzione (px) e densità dei pixel (dpi).

Griglia risoluzioni/densità

Le risoluzioni sono divise in small, normal, large e xlarge mentre le densità in ldpi (low density), mdpi (medium density), hdpi (high density) e xhdpi (extra high density).

Come avevamo accennato, anche per Google uno schermo normale è HVGA: tuttavia dalla pagina Screen Sizes and Densities su Android Developers risulta che al momento il 75% degli schermi è WVGA (Wide VGA). Riuscire a creare un layout one-size-fits-all (cioè uno per tutti, tipo i 3 moschettieri…) non è banale: per esempio conviene distinguere almeno le interfacce tablet (xlarge) da quelle degli smartphone per questioni di superficie disponibile e soprattutto di usabilità. Dal lato nostro possiamo ingegnerizzare il codice organizzandolo in Fragments (che vedremo prossimamente) e “rimontarlo” a piacimento a seconda del layout attivo in quel momento.

Dimensione vs densità

Quando sviluppiamo un’interfaccia grafica per Android, quello di cui dobbiamo preoccuparci non è tanto la dimensione dello schermo quanto la sua densità: sarà questa infatti a pilotare le dimensioni effettive di un elemento sullo schermo. L’importante però è mantenere le proporzioni. Se pensiamo alla Home per esempio, indipendentemente dalla risoluzione e delle dimensioni dello schermo, essa contiene sempre quattro icone: questo risultato si ottiene utilizzando un’unità di misura indipendente dai pixel chiamata density-independent pixel.

Un Density-Independent Pixel (dp) è equivalente ad 1px su uno schermo da 160dpi, ovvero la densità base riferita ad uno schermo a densità media. A runtime poi le dimensioni vengono scalate in base ai dp specificati e alla risoluzione effettiva. A chi piace la matemarica risulterà più chiaro che 1 pixels = DP * (DPI / 160).

Se abbiamo a che fare con immagini la situazione è più complicata perché non possiamo prescindere dalle 4 risoluzioni consigliate da Google: usare una immagine a bassa risoluzione in uno schermo ad alta infatti non è consigliabile (a meno che non vi piaccia l’effetto “pixelloni” anni ’80). Proprio per questo motivo ogni progetto Android è pronto a gestire le 4 risoluzioni! Se non stiamo attenti si rischia di avere immagini non adatte alla risoluzione corrente come in figura:

Stessa immagine, risoluzioni diverse

Inserendo una icona 100×100 px a 72 pdi su uno schermo ldpi, apparirà grande e sgranata. Al contrario, la stessa immagine su uno schermo hdpi apparirà troppo piccola!

Scalare le immagini

Nel caso si abbia a che fare con una immagine da 100×100 px, è necessario che venga riadattata per le 4 densità secondo il rapporto 3:4:6:8 tra le 4 densità. Se quindi la risoluzione base (100) è mdpi (che corrisponde al rapporto 4) si ottiene:

  • ldpi: 75 × 75, cioè 3/4 della risoluzione base (100 * 3 / 4 = 75);
  • mdpi: 100 × 100;
  • hdpi: 150 × 150, cioè una volta e mezzo la risoluzione base (100 * 6 / 4 = 100 * 3 / 2 = 100 * 1,5 = 150);
  • xhdpi: 200 × 200, cioè il doppio della risoluzione base (100 * 8 / 4 = 100 * 2 = 200) a queste risoluzioni dovrebbe corrispondere Google TV, non gli smartophones.

Dovremo quindi produrre 4 immagini:

Immagini necessarie per copire le 4 densità

Ok, abbiamo creato le immagini. E adesso? Come faccio a dire ad Android quale usare? Fortunatamente questo non spetta a noi. Basta infatti creare nella cartella res del progetto Android opportune sotto-cartelle che seguono la seguente nomenclatura:

  • drawable
  • drawable-ldpi
  • drawable-mdpi
  • drawable-hdpi
  • drawable-xhdpi

E la prima cartella cosa conterrà? Come è facile intuire, in essa verranno inseriti tutti i file che non dipendono dalla risoluzione. Gli unici in grado di poter scalare senza sgranare sono i file SVG o le shape drawable.

Conclusioni

La diversificazione ha portato Android a crescere notevolmente in un breve arco di tempo. Ha portato però anche noi sviluppatori a doverci preoccupare di gestire le diverse tipologie di schermo di cui sono dotati i telefoni Android. Grazie però ad un efficiente sistema di gestione delle risorse, si riesce ad aggirare il problema in diversi modi, sfruttando i formati scalabili o creando diverse versioni di una immagine. A mio avviso conviene imparare a sfruttare, dove possibile, uno strumento come le shape drawable per la grande flessibilità che comportano. Ringraziamo Smashing Magazine per aver ispirato questo post.

By Andrea Como

Sono un software engineer focalizzato nella progettazione e sviluppo di applicazioni web in Java. Presso OmniaGroup ricopro il ruolo di Tech Leader sulle tecnologie legate alla piattaforma Java EE 5. In particolare: WebSphere 7.0, EJB3, JPA 1 (EclipseLink), JSF 1.2 (Mojarra) e RichFaces. In passato ho lavorato con la piattaforma alternativa alla enterprise per lo sviluppo web: Java SE 6, Tomcat 6, Hibernate 3 e Spring 2.5. Ultimamente mi sono appassionato al mondo mobile e in particolare ad Android per i motivi che potete immaginare seguendo questo blog! Nei ritagli di tempo invece sviluppo siti web in PHP e ASP e condivido le mie esperienze lavorative sul blog CoseNonJaviste. Per maggiori informazioni consulta il mio curriculum pubblico.

6 comments

  1. Salve. Per cui l’immagina da mettere nelle varie cartelle ad esempio nella cartella drawable-ldpi è di 75×75 px oppure 75×75 dpi? se uso adobe illustrator quando mi esporto l’immagine in vettoriale in .png da File –> save image for web & device c’è solamente px.

    1. Ciao, il sistema lavora sempre in px, quindi l’immagine sarà 75x75x120dpi, per ottenere il calcolo dei px necessari al mdpi, basta convertire (da photoshop o altro programma di grafica) i 120 dpi in 160 dpi, a questo punto otterrai il calcolo matematico, sulla base square pixel.
      Io lavoro in Illustrator, per esportare in png, creo un documento in photoshop con le dimensioni necessarie al mio lavoro e a fine lavoro esporto. Con photoshop puoi tranquillamente gestire i dpi, cosa che in illustrator non avviene in modo “comodo”.

      spero di essere stato d’aiuto 🙂

  2. Ciao, nn mi è chiara una cosa: x esempio la LDPI 75X75px la devo salvare a 120dpi? o a 72dpi come ho fatto fino ad ora? ^_^

    Ciao, grazieeeeee

    W.

  3. ciao ho un tablet con schermo da 7 pollici con aspect ratio da 16:9
    però android esce con un arisoluzione 16:10 (800X480), con conseguenza che è tutto un po schiacciato sul lato corto. C è una maniera di cambiare la risoluzione in 854X480 oppure 800X450 insomma per evitare l effetto deformato?

  4. Ciao! Ti faccio i complimenti per l’articolo! Per chi come me si sta avvicinando al mondo Android penso sia di fondamentale importanza!

    Mi ha chiarito molti dubbi! Devo dirti che ho passato diverse ore a rivedere l’articolo le specifiche android ed i due articoli inglesi che citi nelle fonti!

    Sono arrivato alla conclusione che riuscirei con le stesse immagine oppurtunamente scalate (secondo la forumla), a coprire i display size: small e normal, nelle 4 density: ldpi, mdpi, hdpi, xhdpi.

    Mi resterebbe fuori però la grafica per i display smartphone size: Large con relative densità.

    Quello che ancora mi sfugge…. è possibile avere altre cartelle density specifiche per questo formato (size: large) all’interno dello stesso progetto tipo magari nominabili es. large-ldpi, large-mdpi, ecc per differenziarle da quelle che utilizzari per gli altri scrren size?

    Oppure per non voler scendere a nessun compromesso sulla grafica devo duplicare il progetto facendo 2 versioni per smartphone?

    1. Per display size: small e normal
    2′ Per display size: Large

    Ringrazio chiunque possa venire in mio soccorso!

    Saluti
    Edoardo

Leave a comment

Your email address will not be published.