Verschiedene Pixeldichten unterstützen

Android-Geräte haben nicht nur unterschiedliche Bildschirmgrößen wie Mobilgeräte, Tablets, Fernseher, aber auch Bildschirme mit unterschiedlichen Pixelgrößen. Eins kann dieses Gerät 160 Pixel pro Zoll haben, während ein anderes Gerät mit 480 Zoll Pixel im selben Bereich. Wenn Sie diese Abweichungen bei der kann das System die Pixeldichte Dies führt zu unscharfen Bildern in der falschen Größe angezeigt.

Auf dieser Seite erfahren Sie, wie Sie Ihre App verschiedene Pixeldichten mithilfe von auflösungsunabhängigen Maßeinheiten und alternative Bitmapressourcen für jede Pixeldichte bereitstellen.

Im folgenden Video erhalten Sie einen Überblick über diese Techniken.

Weitere Informationen zum Entwerfen von Symbol-Assets finden Sie in den Richtlinien für Symbole in Material Design.

Dichteunabhängige Pixel verwenden

Vermeiden Sie die Verwendung von Pixeln, um Abstände oder Größen zu definieren. Definieren von Dimensionen mit sind Pixel ein Problem, weil verschiedene Bildschirme unterschiedliche Pixeldichten sodass die gleiche Anzahl von Pixeln verschiedenen physischen Größen auf auf unterschiedlichen Geräten.

<ph type="x-smartling-placeholder">
</ph> Ein Bild, das zwei Beispielgeräte mit unterschiedlicher Dichte zeigt <ph type="x-smartling-placeholder">
</ph> Abbildung 1: Zwei Bildschirme derselben Größe können eine unterschiedliche Anzahl von Pixeln haben.

Um die sichtbare Größe der Benutzeroberfläche beizubehalten Bildschirmen mit unterschiedlicher Dichte, gestalten Sie Ihre Benutzeroberfläche dichteunabhängige Pixel (dp) als Maßeinheit. Ein dp entspricht einem virtuelle Pixeleinheit, die auf einem Bildschirm mit mittlerer Dichte in etwa einem Pixel entspricht (160 dpi). Android übersetzt diesen Wert in den angemessene Anzahl realer Pixel für die jeweilige Dichte.

Betrachten Sie die beiden Geräte in Abbildung 1. Eine Ansicht, die Eine Breite von 100 Pixel erscheint auf dem Gerät links viel größer. Ein Blick mit einer Breite von 100 dp auf beiden Bildschirmen gleich groß ist.

Beim Definieren von Textgrößen können Sie stattdessen skalierbare Pixel (sp) als Maßeinheiten angegeben. Die sp-Einheit ist hat standardmäßig die gleiche Größe wie dp, passt sich jedoch an die bevorzugte Größe des Nutzers an. Textgröße. Verwenden Sie für Layoutgrößen niemals „sp“.

Um beispielsweise den Abstand zwischen zwei Ansichten festzulegen, verwenden Sie dp:

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

Verwenden Sie zum Angeben der Textgröße sp:

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

dp-Einheiten in Pixeleinheiten konvertieren

In einigen Fällen müssen Sie die Abmessungen in dp angeben in Pixel konvertieren. Umwandlung von dp-Einheiten in Bildschirmpixel lautet:

px = dp * (dpi / 160)

Hinweis:Für die Pixelberechnung sollten Sie diese Gleichung niemals hartcodieren. Verwenden Sie stattdessen TypedValue.applyDimension(), das viele Dimensionen (dp, sp usw.) in Pixel konvertiert.

Stellen Sie sich eine App vor, in der eine Scroll- oder Schleppbewegung erkannt wird. nachdem der Finger des Nutzers mindestens 16 Pixel bewegt wurde. Im Normalbereich muss der Finger 16 pixels / 160 dpi, was 2,5 mm entspricht, bewegen, bevor die Geste erkannt wird.

Auf einem Gerät mit einem HD-Display (240 dpi) muss sich der Finger bewegen, 16 pixels / 240 dpi, die entspricht 1,7 mm. Die Strecke ist viel kürzer und wirkt die App daher für den Nutzer empfindlicher.

Um dieses Problem zu beheben, geben Sie den Grenzwert für Touch-Gesten im Code in dp und und wandeln sie dann in Pixel um. Beispiel:

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...

Das Feld DisplayMetrics.density gibt den Skalierungsfaktor an, der zum Umwandeln von dp-Einheiten in der aktuellen Pixeldichte entspricht. Auf einem Bildschirm mit mittlerer Dichte DisplayMetrics.density ist gleich 1,0 und auf einem Display mit hoher Dichte 1,5. Auf einem Bildschirm mit sehr hoher Dichte und auf einem Bildschirm mit niedriger Punktdichte 0,75. Diese Zahl entspricht von TypedValue.applyDimension() verwendet für die tatsächliche Anzahl der Pixel für den aktuellen Bildschirm ermitteln.

Vorskalierte Konfigurationswerte verwenden

Mit der Klasse ViewConfiguration können Sie auf allgemeine Entfernungen, Geschwindigkeiten und Zeiten, die das Android-System verwendet. Zum Beispiel Abstand in Pixeln, die vom Framework als Scroll-Schwellenwert verwendet werden kann mit getScaledTouchSlop():

Kotlin

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

Java

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

Methoden in ViewConfiguration, die mit dem Präfix getScaled beginnen geben immer einen Wert in Pixeln zurück, die unabhängig von der aktuellen die Pixeldichte.

Ich bevorzuge Vektorgrafiken

Eine Alternative zur Erstellung mehrerer dichtespezifischer Versionen eines Bilds besteht darin, nur eine Vektorgrafik erstellen. Vektorgrafiken erstellen ein Bild mithilfe von XML, um Pfade und Farben zu definieren, anstatt Pixel-Bitmaps zu verwenden. Daher kann Vektoren Grafiken lassen sich ohne Skalierung von Artefakten auf jede beliebige Größe skalieren, obwohl sie normalerweise am besten für Illustrationen wie Symbole und nicht für Fotos geeignet.

Vektorgrafiken werden oft als SVG-Dateien (Scaling Vector Graphics) zur Verfügung gestellt. aber Android unterstützt dieses Format nicht. Du musst SVG-Dateien Der Vektor von Android Drawable-Format.

Du kannst eine SVG-Datei mithilfe der Vektor-Asset Studio wie folgt:

  1. Klicken Sie im Fenster Project mit der rechten Maustaste auf das Verzeichnis res und wählen Sie Neu > Vektor-Asset.
  2. Wählen Sie Lokale Datei (SVG, PSD) aus.
  3. Suchen Sie die Datei, die Sie importieren möchten, und nehmen Sie ggf. Änderungen vor.

    <ph type="x-smartling-placeholder">
    </ph> Ein Bild, das zeigt, wie SVGs in Android Studio importiert werden <ph type="x-smartling-placeholder">
    </ph> Abbildung 2: SVG-Datei importieren mit Android Studio

    Möglicherweise werden im Fenster Asset Studio Fehler angezeigt. Dies deutet darauf hin, dass einige Eigenschaften der Datei von Vektor-Drawables nicht unterstützt werden. Sie können die Datei aber trotzdem importieren. nicht unterstützten Eigenschaften werden ignoriert.

  4. Klicken Sie auf Weiter.

  5. Bestätigen Sie auf dem nächsten Bildschirm den Quellsatz, in dem die Datei im Projekt gespeichert werden soll. und klicken Sie auf Fertigstellen.

    Da ein Vektor-Drawable für alle Pixeldichten verwendet werden kann, in Ihr Standard-Drawables-Verzeichnis verschoben, wie im Folgenden Hierarchie. Sie müssen keine dichtespezifischen Verzeichnisse verwenden.

    res/
      drawable/
        ic_android_launcher.xml
    

Weitere Informationen zum Erstellen von Vektorgrafiken findest du im Vektor-Drawable Dokumentation.

Alternative Bitmaps bereitstellen

Um auf Geräten mit unterschiedlichen Pixeldichten eine gute Grafikqualität zu erzielen, Stellen Sie mehrere Versionen jeder Bitmap in Ihrer App bereit – eine für jede Bitmap. mit der entsprechenden Auflösung. Andernfalls muss Android skalieren. Ihre Bitmap so, dass sie auf jedem Bildschirm denselben sichtbaren Bereich einnimmt, sodass Skalierungsartefakte wie Unkenntlichmachung.

<ph type="x-smartling-placeholder">
</ph> Ein Bild, das relative Größen für Bitmaps mit unterschiedlicher Dichte zeigt <ph type="x-smartling-placeholder">
</ph> Abbildung 3: Relative Größen für Bitmaps in verschiedenen Dichte-Buckets.

In Ihren Anwendungen stehen mehrere Dichte-Buckets zur Verfügung. Tabelle 1 werden die verschiedenen verfügbaren Konfigurationsqualifizierer und Bildschirmtypen beschrieben. für die sie gelten.

Tabelle 1 Konfigurationsqualifizierer für verschiedene Pixeldichten.

Dichte-Qualifier Beschreibung
ldpi Ressourcen für Bildschirme mit niedriger Dichte (ldpi) (ca. 120 dpi).
mdpi Ressourcen für Bildschirme mittlerer Dichte (mdpi) (ca. 160 dpi). Das ist die Baseline Dichte.
hdpi Ressourcen für Bildschirme mit hoher Dichte (hdpi) (ca. 240 dpi).
xhdpi Ressourcen für Bildschirme mit besonders hoher Dichte (xhdpi) (ca. 320 dpi)
xxhdpi Ressourcen für Bildschirme mit besonders hoher Dichte (xxhdpi) (~480 dpi)
xxxhdpi Ressourcen für die Verwendung besonders hoher Dichte (xxxhdpi) (ca. 640 dpi)
nodpi Ressourcen für alle Dichten. Dies sind dichteunabhängige Ressourcen. Das System nutzt Skalierung von Ressourcen, die mit diesem Qualifier getaggt sind, unabhängig von der aktuellen Bildschirmdichte.
tvdpi Ressourcen für Bildschirme irgendwo zwischen mdpi und hdpi; ungefähr ca. 213 dpi. Dies gilt nicht als „primär“ Dichtegruppe. Sie ist hauptsächlich dazu gedacht, für Fernseher und die meisten Apps brauchen sie nicht – mit mdpi und hdpi. Ressourcen sind für die meisten Anwendungen ausreichend und werden vom System angemessen sein. Wenn Sie die Bereitstellung von tvdpi-Ressourcen für erforderlich halten, mit dem Faktor 1,33 * mdpi. Ein Bild mit 100 x 100 Pixeln für mdpi-Bildschirme haben eine Größe von 133 x 133 Pixel für tvdpi.

Um alternative Bitmap-Drawables für verschiedene Dichten zu erstellen, Skalierungsverhältnis zwischen den sechs primären Dichten von 3:4:6:8:12:16. Wenn Sie beispielsweise Bitmap-Drawable mit 48 x 48 Pixeln für Bildschirme mit mittlerer Dichte sind folgende Größen:

  • 36 × 36 (0,75 ×) für niedrige Dichte (ldpi)
  • 48 x 48 (1,0-fache Referenz) für mittlere Dichte (mdpi)
  • 72 x 72 (1,5x) für High Density (hdpi)
  • 96 × 96 (2,0 ×) für besonders hohe Dichte (xhdpi)
  • 144 x 144 (3,0 x) für besonders hohe Dichte (xxhdpi)
  • 192 x 192 (4,0 x) für besonders besonders hohe Dichte (xxxhdpi)

Legen Sie die generierten Bilddateien im entsprechenden Unterverzeichnis ab. unter 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

Wenn Sie dann auf @drawable/awesomeimage verweisen, wählt das System die Bitmap basierend auf der Bildschirmdpi aus. Wenn Sie keine spezifische Ressource für diese Dichte bereitstellen, sucht das System die nächstbeste Übereinstimmung und skaliert sie, um sie an den Bildschirm anzupassen.

Tipp:Wenn Sie Drawable-Ressourcen haben dass das System nicht skaliert werden soll, einige Anpassungen am Bild vornehmen, nehmen Sie diese mit dem Konfigurationsqualifizierer nodpi. Ressourcen mit diesem Qualifier werden als dichteunabhängig betrachtet. werden sie vom System nicht skaliert.

Weitere Informationen zu anderen Konfigurationsqualifizierern und wie Android die passenden Ressourcen für Informationen zur aktuellen Bildschirmkonfiguration finden Sie in der Übersicht zu App-Ressourcen.

App-Symbole in Mipmap-Verzeichnisse einfügen

Wie bei anderen Bitmap-Assets müssen Sie dichtespezifische Versionen Ihr App-Symbol. In einigen App Launchern wird das App-Symbol jedoch zu 25 % angezeigt. die vom Dichte-Bucket des Geräts vorgegeben sind.

Wenn die Dichte des Buckets eines Geräts beispielsweise xxhdpi beträgt und das größte App-Symbol in drawable-xxhdpi ist, wird dieses Symbol vom App Launcher vergrößert, Dadurch wirkt sie weniger knackig.

Um dies zu vermeiden, Ihre App-Symbole in mipmap-Verzeichnissen statt in drawable-Verzeichnissen. „Mag ich“-Bewertung entfernen drawable-Verzeichnisse werden alle mipmap-Verzeichnisse im APK beibehalten, auch wenn Sie dichtespezifische APKs erstellen. So können Launcher-Apps die besten Symbol für die Auflösung, das auf dem Startbildschirm angezeigt wird.

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

Im vorherigen Beispiel für ein xxhdpi-Gerät höher kompakteres Launcher-Symbols im Verzeichnis mipmap-xxxhdpi.

Richtlinien zur Gestaltung von Symbolen finden Sie unter Systemsymbole.

Weitere Informationen zum Erstellen von App-Symbolen finden Sie unter App-Symbole mit Image Asset Studio erstellen.

Tipps bei ungewöhnlichen Kompaktheitsgrad-Problemen

In diesem Abschnitt wird beschrieben, wie Android die Skalierung von Bitmaps durchführt und wie Sie genauer steuern können, wie Bitmaps werden mit verschiedenen Dichten gezeichnet. Es sei denn, Ihre App manipuliert Grafiken. oder bei der Ausführung mit unterschiedlichen Pixeldichten Probleme aufgetreten sind, können Sie diesen Abschnitt ignorieren.

Um besser zu verstehen, wie Sie mehrere Dichten unterstützen können, wenn Sie Grafiken bei müssen Sie wissen, wie das System dafür sorgt, dass Bitmaps korrekt skaliert werden. Dies geschieht auf folgende Weise:

  1. Vorskalierung von Ressourcen, z. B. Bitmap-Drawables

    Basierend auf der Dichte des aktuellen Bildschirms verwendet das System Ressourcen aus Ihrer App. Wenn keine Ressourcen verfügbar sind in mit der richtigen Dichte, lädt das System die Standardressourcen und skaliert sie nach Bedarf hoch oder herunter. Das System geht davon aus, dass Standardressourcen ohne Konfigurationsqualifizierer) werden für die Referenzversion (mdpi) und passt die Größe dieser Bitmaps der aktuellen Pixeldichte.

    Wenn Sie die Dimensionen einer vorab skalierten Ressource anfordern, gibt das System Werte zurück Darstellung der Dimensionen nach der Skalierung. Zum Beispiel eine Bitmap, die mit 50 x 50 Pixeln für einen mdpi-Bildschirm auf 75 x 75 Pixel auf einem hdpi-Bildschirm skaliert wird (wenn es keine alternative Ressource gibt) für HDPI) und das System meldet die Größe entsprechend.

    Es gibt Situationen, in denen Sie nicht möchten, dass Android eine Ressource. Die einfachste Möglichkeit, eine Vorskalierung zu vermeiden, besteht darin, die Ressource in einem Ressourcenverzeichnis abzulegen. mit dem Konfigurationsqualifizierer nodpi. Beispiel:

    res/drawable-nodpi/icon.png

    Wenn das System die Bitmap icon.png aus diesem Ordner verwendet, wird sie nicht skaliert basierend auf der aktuellen Gerätedichte.

  2. Automatische Skalierung von Pixeldimensionen und -koordinaten

    Sie können das Vorskalieren von Dimensionen und Bildern deaktivieren, indem Sie android:anyDensity festlegen im Manifest auf "false" oder programmatisch für ein Bitmap-Objekt, indem Sie inScaled auf "false" setzen. In In diesem Fall skaliert das System automatisch alle absoluten Pixelkoordinaten und Dimensionswerte auswählen. Damit wird sichergestellt, dass pixelbasierte Bildschirmelemente werden immer noch in etwa derselben Größe angezeigt dass sie mit der Basispixeldichte (mdpi) angezeigt werden können. Das System verarbeitet die transparent an die App skaliert und das skalierte Pixel statt der physischen Pixelabmessungen zur App.

    Angenommen, ein Gerät verfügt über einen WVGA-HD-Bildschirm, der 480 x 800 Pixel groß ist und in etwa die gleiche Größe wie ein herkömmlicher HVGA-Bildschirm hat, Vorskalierung. In diesem Fall „liegt“ das System wenn nach einem Bildschirm gefragt wird, und gibt 320 × 533 aus, die ungefähre mdpi-Übersetzung für die Pixeldichte.

    Wenn dann Die App führt Zeichenvorgänge aus, wie z. B. das Entwerten eines Rechtecks von (10,10) bis (100, 100), transformiert das System die Koordinaten, indem es sie um die entsprechende Größe skaliert, und tatsächlich die Region (15,15) bis (150, 150) ungültig macht. Diese Abweichung kann zu unerwartetem Verhalten führen, wenn dass Ihre App die skalierte Bitmap direkt manipuliert. Dies wird jedoch um die bestmögliche App-Leistung zu erzielen. In diesem Fall lesen Sie den Abschnitt Einheiten dp in Pixel konvertieren Einheiten.

    Normalerweise deaktivieren Sie die Vorskalierung nicht. Die beste Möglichkeit, mehrere ist, den auf dieser Seite beschriebenen grundlegenden Techniken zu folgen.

Ihre App manipuliert Bitmaps oder interagiert direkt mit Pixeln auf dem Bildschirm müssen Sie möglicherweise zusätzliche Schritte unternehmen, um Pixeldichten. Wenn Sie beispielsweise auf Touch-Gesten reagieren, indem Sie die die mit dem Finger gekreuzt wird, müssen Sie das entsprechende dichteunabhängige Pixelwerte anstelle von tatsächlichen Pixeln. Sie können Konvertieren Sie zwischen dp- und px-Werten.

Mit allen Pixeldichten testen

App auf mehreren Geräten mit unterschiedlichem Pixel testen damit Ihre UI korrekt skaliert wird. Testen an einem physischen Gerät nach Möglichkeit verwenden; verwenden Sie die Android- Emulator, wenn Sie keinen Zugriff auf physische Geräte für die verschiedenen Pixeldichten.

Wenn Sie Tests auf physischen Geräten durchführen möchten, die Geräte nicht kaufen möchten, können Sie mit dem Firebase Test Lab auf Geräte in einem Google-Rechenzentrum.