Supporta densità di pixel diverse

I dispositivi Android non solo hanno schermi di dimensioni diverse: telefoni, tablet, TV e così via, ma anche schermi con dimensioni in pixel diverse. Uno. potrebbe avere 160 pixel per pollice, mentre un altro dispositivo potrebbe avere pixel nello stesso spazio. Se non prendi in considerazione queste variazioni densità dei pixel, il sistema potrebbe scalare le tue immagini, generando immagini sfocate, oppure le immagini potrebbero non siano corretti.

Questa pagina mostra come progettare l'app per supportare densità dei pixel diverse utilizzando unità di misura indipendenti dalla risoluzione e fornendo risorse bitmap alternative per ogni densità di pixel.

Guarda il seguente video per una panoramica di queste tecniche.

Per ulteriori informazioni sulla progettazione di asset per icone, consulta le linee guida per le icone di Material Design.

Utilizza pixel indipendenti dalla densità

Evita di utilizzare i pixel per definire le distanze o le dimensioni. La definizione delle dimensioni con è un problema perché schermi diversi hanno densità di pixel diverse, pertanto lo stesso numero di pixel corrisponde a dimensioni fisiche diverse su dispositivi diversi.

Un'immagine che mostra due esempi di dispositivi con densità diverse
. Figura 1: due schermate delle stesse dimensioni possono avere un numero di pixel diverso.

Per mantenere le dimensioni visibili della UI su schermi con densità diverse, progetta la tua UI utilizzando pixel indipendenti dalla densità (dp) come unità di misura. Un dp è un unità pixel virtuale uguale a circa 1 pixel su uno schermo a media densità (160 dpi, o densità di riferimento). Android converte questo valore numero appropriato di pixel reali per l'altra densità.

Considera i due dispositivi nella Figura 1. Una vista che Una larghezza di 100 pixel appare molto più grande sul dispositivo a sinistra. Una vista una larghezza di 100 dp appare delle stesse dimensioni su entrambi gli schermi.

Quando definisci le dimensioni del testo, puoi invece utilizzare scalabile pixel (sp) come unità. L'unità sp è ha le stesse dimensioni di un dp per impostazione predefinita, ma viene ridimensionato in base alle preferenze dell'utente dimensioni del testo. Non utilizzare mai sp per le dimensioni di layout.

Ad esempio, per specificare la spaziatura tra due visualizzazioni, utilizza dp:

<Button android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/clickme"
    android:layout_marginTop="20dp" />

Quando specifichi la dimensione del testo, utilizza sp:

<TextView android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="20sp" />

Converti le unità dp in unità pixel

In alcuni casi, devi esprimere le dimensioni in dp e poi convertirli in pixel. La conversione delle unità dp in pixel dello schermo è il seguente:

px = dp * (dpi / 160)

Nota: non impostare mai questa equazione come hardcoded per il calcolo dei pixel. Utilizza invece TypedValue.applyDimension(), che converte automaticamente molti tipi di dimensioni (dp, sp e così via) in pixel.

Immagina un'app in cui viene riconosciuto un gesto di scorrimento o scorrimento una volta spostato il dito di almeno 16 pixel. In linea con il valore basale schermo, il dito di un utente deve spostare 16 pixels / 160 dpi, ovvero 1/10 di pollice (o 2,5 mm), prima il gesto viene riconosciuto.

Su un dispositivo Con un display ad alta densità (240 dpi), l'utente deve spostare il dito 16 pixels / 240 dpi, che equivale a 1/15 di pollice (o 1,7 mm). La distanza è molto più corta e pertanto l'app appare più sensibile all'utente.

Per risolvere il problema, esprimi la soglia dei gesti nel codice in dp e quindi convertirlo in pixel veri e propri. Ad esempio:

Kotlin

// The gesture threshold expressed in dp
private const val GESTURE_THRESHOLD_DP = 16.0f

private var gestureThreshold: Int = 0

// Convert the dps to pixels, based on density scale
gestureThreshold = TypedValue.applyDimension(
  COMPLEX_UNIT_DIP,
  GESTURE_THRESHOLD_DP + 0.5f,
  resources.displayMetrics).toInt()

// Use gestureThreshold as a distance in pixels...

Java

// The gesture threshold expressed in dp
private final float GESTURE_THRESHOLD_DP = 16.0f;

// Convert the dps to pixels, based on density scale
int gestureThreshold = (int) TypedValue.applyDimension(
  COMPLEX_UNIT_DIP,
  GESTURE_THRESHOLD_DP + 0.5f,
  getResources().getDisplayMetrics());

// Use gestureThreshold as a distance in pixels...

Il campo DisplayMetrics.density specifica il fattore di scala utilizzato per convertire le unità dp in pixel in base alla densità di pixel corrente. Su uno schermo a media densità, DisplayMetrics.density è uguale a su uno schermo ad alta densità è pari a 1, 5. Su uno schermo ad altissima densità, è uguale a 2, 0 e su uno schermo a bassa densità è pari a 0, 75. Questo valore è usata da TypedValue.applyDimension() per ottenere il numero di pixel per la schermata corrente.

Utilizza i valori di configurazione prescalati

Puoi utilizzare la classe ViewConfiguration per accedere distanze, velocità e tempi usati dal sistema Android. Ad esempio, distanza in pixel utilizzata dal framework come soglia di scorrimento con getScaledTouchSlop():

Kotlin

private val GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).scaledTouchSlop

Java

private final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();

Metodi in ViewConfiguration che iniziano con il prefisso getScaled restituiscono un valore in pixel che vengono visualizzati correttamente, indipendentemente dallo stato densità dei pixel.

Preferisco la grafica vettoriale

Un'alternativa alla creazione di più versioni di un'immagine specifiche della densità è la per creare una sola grafica vettoriale. Le grafiche vettoriali creano un'immagine utilizzando XML per definiscono percorsi e colori invece di utilizzare bitmap di pixel. Di conseguenza, il vettore grafici possono scalare a qualsiasi dimensione senza artefatti di scalabilità, anche se di solito ideale per illustrazioni come icone, non per fotografie.

Le grafiche vettoriali sono spesso fornite come file SVG (Scalable Vector Graphics), Android, però, non supporta questo formato, quindi devi convertire i file SVG in Il vettore di Android drawable.

Puoi convertire un file SVG in un disegno vettoriale utilizzando Vector Asset Studio come segue:

  1. Nella finestra Project, fai clic con il tasto destro del mouse sulla directory res e seleziona Nuovo > Vector Asset.
  2. Seleziona File locale (SVG, PSD).
  3. Individua il file da importare e apporta le modifiche necessarie.

    Un&#39;immagine che mostra come importare SVG in Android Studio
    . Figura 2: importazione di un file SVG con Android Studio.

    Potresti notare alcuni errori nella finestra di Asset Studio che indica che i drawable vettoriali non supportano alcune proprietà del file. Ciò non ti impedisce di importare il file. le proprietà non supportate vengono ignorati.

  4. Fai clic su Avanti.

  5. Nella schermata successiva, conferma il set di origine in cui vuoi inserire il file nel progetto e fai clic su Fine.

    Poiché è possibile usare un solo drawable vettoriale su tutte le densità di pixel, questo file viene inserito nella directory drawables predefinita, come mostrato di seguito nella gerarchia. Non è necessario utilizzare directory specifiche per la densità.

    res/
      drawable/
        ic_android_launcher.xml
    

Per ulteriori informazioni sulla creazione di grafiche vettoriali, leggi la sezione Drawable vettoriale documentazione.

Fornire bitmap alternative

Per offrire una buona qualità grafica su dispositivi con densità di pixel diverse, fornire più versioni di ogni bitmap nella tua app, una per ogni ad alta densità, a una risoluzione corrispondente. Altrimenti, Android deve scalare la bitmap in modo che occupi lo stesso spazio visibile su ogni schermo, ottenendo artefatti di scalabilità, come la sfocatura.

Un&#39;immagine che mostra dimensioni relative per bitmap con densità diverse
. Figura 3: dimensioni relative delle bitmap in bucket di densità diversi.

Sono disponibili diversi bucket di densità disponibili per l'uso nelle tue app. Tabella 1 descrive i diversi qualificatori di configurazione disponibili e i tipi di schermata a cui si applicano.

Tabella 1. Qualificatori di configurazione per densità dei pixel.

Qualificatore densità Descrizione
ldpi Risorse per schermi a bassa densità (ldpi) (~120 dpi).
mdpi Risorse per schermi a media densità (mdpi) (~160 dpi). Questa è la base di riferimento una densità di dati molto elevata.
hdpi Risorse per schermi ad alta densità (hdpi) (~240 dpi).
xhdpi Risorse per schermi ad alta densità (xhdpi) (~320 dpi).
xxhdpi Risorse per schermi ad altissima densità (xxhdpi) (~480 dpi).
xxxhdpi Risorse per utilizzi a densità molto elevata (xxxhdpi) (~640 dpi).
nodpi Risorse per tutte le densità. Si tratta di risorse indipendenti dalla densità. Il sistema non scala le risorse contrassegnate con questo qualificatore, a prescindere dalla densità della schermata corrente.
tvdpi risorse per gli schermi a metà strada tra mdpi e hdpi; circa ~213 dpi Questo elemento non è considerato "principale" denso di intensità. È destinata principalmente per i televisori e la maggior parte delle app non ne ha bisogno, fornendo dati mdpi e hdpi sono sufficienti per la maggior parte delle app e il sistema le scala appropriato. Se ritieni necessario fornire risorse di tvdpi, ridimensionarle con un fattore di 1,33 * mdpi. Ad esempio, un'immagine di 100 x 100 pixel per gli schermi mdpi sono 133x133 pixel per tvdpi.

Per creare drawable bitmap alternativi per densità diverse, segui la Rapporto di scalabilità 3:4:6:8:12:16 tra le sei densità primarie. Ad esempio, se disponi di cui è possibile ottenere una bitmap di 48x48 pixel per schermi a media densità, le dimensioni sono:

  • 36 x 36 (0,75x) per bassa densità (ldpi)
  • 48 x 48 (base 1,0x) per densità media (mdpi)
  • 72x72 (1,5x) per alta densità (hdpi)
  • 96 x 96 (2,0x) per l’alta densità (xhdpi)
  • 144 x 144 (3,0x) per densità extra-alta (xxhdpi)
  • 192 x 192 (4,0x) per densità extra-extra-alta (xxxhdpi)

Inserisci i file immagine generati nella sottodirectory appropriata sotto res/:

res/
  drawable-xxxhdpi/
    awesome_image.png
  drawable-xxhdpi/
    awesome_image.png
  drawable-xhdpi/
    awesome_image.png
  drawable-hdpi/
    awesome_image.png
  drawable-mdpi/
    awesome_image.png

Ogni volta che fai riferimento a @drawable/awesomeimage, il sistema seleziona la bitmap appropriata in base ai DPI dello schermo. Se non forniscono una risorsa specifica per tale densità, il sistema individua la migliore corrispondenza e la ridimensiona per adattarsi allo schermo.

Suggerimento: se hai risorse disegnabili che non vuoi che il sistema scali, ad esempio quando esegui alcune modifiche all'immagine in fase di runtime, inseriscile in una con il qualificatore di configurazione nodpi. Le risorse con questo qualificatore sono considerate indipendenti dalla densità il sistema non le scala.

Per ulteriori informazioni sugli altri qualificatori di configurazione il modo in cui Android seleziona le risorse appropriate l'attuale configurazione della schermata, consulta la panoramica delle risorse per le app.

Inserisci le icone delle app nelle directory mipmap

Come per altri asset bitmap, devi fornire versioni specifiche per la densità di l'icona dell'app. Tuttavia, alcune app in Avvio applicazioni visualizzano l'icona dell'app anche fino al 25%. maggiore di quanto richiesto dal bucket di densità del dispositivo.

Ad esempio, se il bucket di densità di un dispositivo è xxhdpi e l'icona dell'app più grande fornire è in drawable-xxhdpi, Avvio applicazioni scala questa icona, rendendolo meno nitido.

Per evitare che ciò accada, metti tutti le icone delle app nelle directory mipmap anziché in drawable. Non mi piace drawable directory, tutte le mipmap directory vengono conservate nell'APK, anche se crei APK specifici per la densità. Consente alle app Avvio app di scegliere di risoluzione dei problemi da visualizzare sulla schermata Home.

res/
  mipmap-xxxhdpi/
    launcher_icon.png
  mipmap-xxhdpi/
    launcher_icon.png
  mipmap-xhdpi/
    launcher_icon.png
  mipmap-hdpi/
    launcher_icon.png
  mipmap-mdpi/
    launcher_icon.png

Nell'esempio precedente di un dispositivo xxhdpi, puoi fornire un icona Avvio app a densità più elevata nella directory mipmap-xxxhdpi.

Per linee guida relative alla progettazione delle icone, consulta le Icone di sistema.

Per informazioni sulla creazione di icone delle app, consulta la sezione Creare icone delle app con Image Asset Studio.

Consigli per problemi di densità insoliti

In questa sezione viene descritto il ridimensionamento di Android per le bitmap. su diverse densità di pixel e come puoi controllare ulteriormente le bitmap vengono tracciate su densità diverse. A meno che l'app non manipola la grafica o se hai riscontrato problemi durante l'esecuzione su diverse densità di pixel, puoi ignorare questa sezione.

Per comprendere meglio come supportare più densità durante la manipolazione della grafica del runtime, devi sapere in che modo il sistema contribuisce a garantire la scala corretta per le bitmap. Puoi farlo nei seguenti modi:

  1. Pre-scalabilità delle risorse, ad esempio gli elementi risorsa bitmap

    In base alla densità della schermata corrente, il sistema utilizza qualsiasi le risorse dalla tua app. Se le risorse non sono disponibili in la densità corretta, il sistema carica le risorse predefinite e ne fa lo scale up o lo scale down in base alle esigenze. Il sistema presuppone che le risorse predefinite (quelle di un senza qualificatori di configurazione) sono progettati per i densità dei pixel (mdpi) e ridimensionarle alle dimensioni appropriate per l'attuale densità dei pixel.

    Se richiedi le dimensioni di una risorsa pre-scalata, il sistema restituisce dei valori. che rappresentano le dimensioni dopo il ridimensionamento. Ad esempio, una bitmap progettata per 50x50 pixel per una schermata mdpi viene scalata a 75x75 pixel su uno schermo hdpi (se non sono disponibili risorse alternative per hdpi) e il sistema segnala le dimensioni come tali.

    In alcune situazioni potresti non volere che Android pre-scala una risorsa. Il modo più semplice per evitare il pre-scalabilità è posizionare la risorsa in una directory di risorse con il qualificatore di configurazione nodpi. Ad esempio:

    res/drawable-nodpi/icon.png

    Quando il sistema utilizza la bitmap icon.png di questa cartella, non la scala in base all'attuale densità del dispositivo.

  2. Scalabilità automatica di dimensioni e coordinate in pixel

    Puoi disattivare le dimensioni e le immagini di pre-scalabilità impostando android:anyDensity su "false" nel manifest o in modo programmatico per Bitmap impostando inScaled su "false". Nella In questo caso, il sistema scala automaticamente tutte le coordinate di pixel e i pixel assoluti dei valori delle dimensioni al momento del disegno. In questo modo viene assicurato che il modello gli elementi sullo schermo vengono comunque visualizzati all'incirca nelle stesse dimensioni fisiche in modo che possano essere visualizzati alla densità di pixel di base (mdpi). Il sistema gestisce scalando in modo trasparente l'app e riportando il pixel scalato dimensioni all'app anziché dimensioni in pixel fisici.

    Ad esempio, supponiamo che un dispositivo abbia uno schermo WVGA ad alta densità, che è di 480 x 800 e circa delle stesse dimensioni di uno schermo HVGA tradizionale, ma esegue un'app che ha disattivato di prescalabilità. In questo caso, il sistema "mente" all'app quando esegue una query per e genera report 320 x 533, la traduzione mdpi approssimativa per la densità dei pixel.

    Poi, quando l'app esegue operazioni di disegno, ad esempio la convalida di un rettangolo da (10,10) a (100, 100), il sistema trasforma le coordinate scalandole nella quantità adeguata, e in realtà invalida la regione (15,15) a (150, 150). Questa discrepanza può causare comportamenti imprevisti l'app manipola direttamente la bitmap ridimensionata, ma questo è considerato un un compromesso per garantire le migliori prestazioni possibili dell'app. Se riscontri questo leggi l'articolo Convertire unità dp in pixel. unità di misura.

    In genere, non disattivi il pre-scalabilità. Il modo migliore per supportare più schermo è seguire le tecniche di base descritte in questa pagina.

Se la tua app manipola le bitmap o interagisce direttamente con i pixel sullo schermo in altri modi, potresti dover svolgere dei passaggi aggiuntivi per supportare densità dei pixel. Ad esempio, se rispondi ai gesti tattili contando i di pixel che passino con un dito, devi usare la valori dei pixel indipendenti dalla densità, invece dei pixel effettivi, ma puoi convertire valori in dp e px.

Esegui test su tutte le densità dei pixel

Testa l'app su più dispositivi con pixel diversi per garantire il corretto ridimensionamento della UI. Test su un sistema dispositivo quando è possibile; usa l'app Android Emulatore se non hai accesso a dispositivi per tutte le diverse densità di pixel.

Se vuoi eseguire il test su dispositivi fisici, Non vuoi acquistare questi dispositivi, puoi usare Firebase Test Lab per accedere ai dispositivi in un data center Google.