Unterstützung von dreifach faltbaren Geräten und faltbaren Geräten im Querformat

Ein faltbares Smartphone im Querformat in geschlossenem und vollständig geöffnetem Zustand neben einem faltbaren Smartphone mit drei Displays in geschlossenem und vollständig geöffnetem Zustand.

Entwickler stehen oft vor besonderen Herausforderungen, wenn sie Apps für Faltgeräte entwickeln, insbesondere für Geräte wie das Samsung Trifold oder das ursprüngliche Pixel Fold, das im Querformat geöffnet wird (rotation_0 = Querformat). Zu den Fehlern von Entwicklern gehören:

  • Falsche Annahmen zur Geräteausrichtung
  • Übersehene Anwendungsfälle
  • Werte werden bei Konfigurationsänderungen nicht neu berechnet oder im Cache gespeichert.

Zu den gerätespezifischen Problemen gehören:

  • Die natürliche Ausrichtung des Geräts stimmt zwischen dem Cover- und dem inneren Display nicht überein (Annahmen basierend auf „rotation_0 = Hochformat“), was dazu führt, dass Apps beim Ein- und Ausklappen nicht funktionieren.
  • Unterschiedliche Bildschirmdichten und falsche Verarbeitung von Änderungen der density-Konfiguration
  • Probleme mit der Kameravorschau aufgrund der Abhängigkeit des Kamerasensors von der natürlichen Ausrichtung

Damit Nutzer auf faltbaren Geräten eine hochwertige Nutzererfahrung haben, solltest du dich auf die folgenden wichtigen Bereiche konzentrieren:

  • Die Ausrichtung der App wird anhand des tatsächlichen Bildschirmbereichs bestimmt, den die App einnimmt, nicht anhand der physischen Ausrichtung des Geräts.
  • Kameravorschauen aktualisieren, um Geräteausrichtung und Seitenverhältnisse korrekt zu verwalten, seitliche Vorschauen zu vermeiden und gestreckte oder zugeschnittene Bilder zu verhindern
  • Sorgen Sie dafür, dass die App beim Auf- oder Zuklappen des Geräts nicht unterbrochen wird. Behalten Sie dazu den Status mit ViewModel oder ähnlichen Ansätzen bei oder verarbeiten Sie Änderungen der Bildschirmdichte und Ausrichtung manuell, um App-Neustarts oder Statusverluste zu vermeiden.
  • Bei Apps, die Bewegungssensoren verwenden, muss das Koordinatensystem an die aktuelle Ausrichtung des Displays angepasst werden. Vermeiden Sie Annahmen basierend auf rotation_0 = Hochformat, um präzise Nutzerinteraktionen zu gewährleisten.

Adaptive Builds

Wenn Ihre App bereits adaptiv ist und dem in den Qualitätsrichtlinien für Apps für große Displays beschriebenen optimierten Niveau (Tier 2) entspricht, sollte sie auf faltbaren Geräten gut funktionieren. Andernfalls sollten Sie sich die folgenden grundlegenden Konzepte der adaptiven Android-Entwicklung ansehen, bevor Sie die spezifischen Details von faltbaren Geräten mit drei Displays und faltbaren Geräten im Querformat noch einmal überprüfen.

Adaptive Layouts

Ihre Benutzeroberfläche muss nicht nur mit verschiedenen Bildschirmgrößen, sondern auch mit Echtzeitänderungen des Seitenverhältnisses zurechtkommen, z. B. beim Aufklappen und beim Wechsel in den Mehrfenstermodus oder den Desktop-Fenstermodus. Weitere Informationen zu adaptiven Layouts

  • Adaptive Layouts entwerfen und implementieren
  • Primäre Navigation der App an die Fenstergröße anpassen
  • UI Ihrer App mit Fenstergrößenklassen anpassen
  • Vereinfachen Sie die Implementierung kanonischer Layouts wie Listen- und Detailansichten mit den Jetpack-APIs.
Eine App mit Letterboxing auf einem geöffneten faltbaren Gerät und dieselbe App im Vollbildmodus mit einem adaptiven Layout auf einem anderen geöffneten faltbaren Gerät.
Abbildung 1: Unterschied zwischen nicht adaptiven (Letterbox-) und adaptiven Layouts.

Klassen für Fenstergrößen

Faltbare Geräte, einschließlich faltbarer Geräte im Querformat und Trifolds, können sofort zwischen den Fenstergrößenklassen „Kompakt“, „Mittel“ und „Erweitert“ wechseln. Wenn Sie diese Klassen verstehen und implementieren, wird in Ihrer App die richtige Navigation und die richtige Dichte der Inhalte für den aktuellen Gerätestatus angezeigt.

Darstellung einer App auf Geräten mit den Fenstergrößenklassen „Kompakt“, „Mittel“ und „Erweitert“.
Abbildung 2. Klassen für Fenstergrößen.

Im folgenden Beispiel wird die adaptive Material 3-Bibliothek verwendet, um zu ermitteln, wie viel Platz der App zur Verfügung steht. Dazu wird zuerst die Funktion currentWindowAdaptiveInfo() aufgerufen und dann die entsprechenden Layouts für die drei Fenstergrößenklassen verwendet:

val adaptiveInfo = currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)
val windowSizeClass = adaptiveInfo.windowSizeClass

when {
  windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_EXPANDED_LOWER_BOUND) -> // Large
  windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND) -> // Medium
  else -> // Compact
}

Weitere Informationen finden Sie unter Fenstergrößenklassen verwenden.

Qualitätsrichtlinien für Apps für große Displays

Wenn Sie die Richtlinien für App-Qualität auf großen Bildschirmen für Tier 2 (für große Bildschirme optimiert) oder Tier 1 (für große Bildschirme differenziert) einhalten, bietet Ihre App eine ansprechende Nutzererfahrung auf Geräten mit faltbarem Display, Foldables im Querformat und anderen Geräten mit großen Bildschirmen. Die Richtlinien umfassen wichtige Prüfungen auf mehreren Ebenen, um von einer adaptiven zu einer differenzierten Darstellung zu gelangen.

Android 16 oder höher

Bei Apps, die auf Android 16 (API-Ebene 36) und höher ausgerichtet sind, ignoriert das System Einschränkungen für Ausrichtung, Größenänderung und Seitenverhältnis auf Displays mit einer kleinsten Breite von mindestens 600 dp. Apps füllen das gesamte Displayfenster aus, unabhängig vom Seitenverhältnis oder der bevorzugten Ausrichtung des Nutzers. Der Kompatibilitätsmodus Letterboxing wird nicht mehr verwendet.

Besonderheiten

Bei Smartphones mit drei Displays und faltbaren Smartphones im Querformat gibt es einzigartige Hardware-Verhaltensweisen, die eine spezielle Verarbeitung erfordern, insbesondere in Bezug auf Sensoren, Kameravorschau und Konfigurationskontinuität (Beibehalten des Status beim Falten, Entfalten oder Ändern der Größe).

Kameravorschau

Ein häufiges Problem bei faltbaren Geräten im Querformat oder bei der Berechnung des Seitenverhältnisses (in Szenarien wie Multifenster, Desktop-Fenster oder verbundene Displays) ist, wenn die Kameravorschau gestreckt, seitlich, zugeschnitten oder gedreht angezeigt wird.

Nicht übereinstimmende Annahmen

Dieses Problem tritt häufig auf Geräten mit großem Display und faltbaren Geräten auf, da Apps von festen Beziehungen zwischen Kamerafunktionen wie Seitenverhältnis und Sensorausrichtung und Gerätefunktionen wie Geräteausrichtung und natürlicher Ausrichtung ausgehen können.

Neue Formfaktoren stellen diese Annahme infrage. Bei einem faltbaren Gerät können sich die Anzeigegröße und das Seitenverhältnis ändern, ohne dass sich die Ausrichtung des Geräts ändert. Wenn ein Nutzer beispielsweise ein faltbares Gerät aufklappt, ändert sich das Seitenverhältnis, aber wenn er das Gerät nicht dreht, bleibt die Ausrichtung gleich. Wenn eine App davon ausgeht, dass das Seitenverhältnis mit der Gerätedrehung zusammenhängt, kann es sein, dass die Kameravorschau falsch gedreht oder skaliert wird. Das Gleiche kann passieren, wenn eine App davon ausgeht, dass die Ausrichtung des Kamerasensors mit der Ausrichtung eines Geräts im Hochformat übereinstimmt. Das ist bei faltbaren Geräten im Querformat nicht immer der Fall.

Lösung 1: Jetpack CameraX (am besten)

Die einfachste und stabilste Lösung ist die Verwendung der Jetpack CameraX-Bibliothek. Das PreviewView-UI-Element wurde entwickelt, um alle Komplexitäten der Vorschau automatisch zu verarbeiten:

  • PreviewView wird korrekt an die Sensorausrichtung, die Gerätedrehung und die Skalierung angepasst.
  • Das Seitenverhältnis des Kamerabilds wird beibehalten, in der Regel durch Zentrieren und Zuschneiden (FILL_CENTER).
  • Sie können den Skalierungstyp auf FIT_CENTER festlegen, um die Vorschau bei Bedarf zu letterboxen.

Weitere Informationen finden Sie in der CameraX-Dokumentation unter Implement a preview.

Lösung 2: CameraViewfinder

Wenn Sie eine vorhandene Camera2-Codebasis verwenden, ist die CameraViewfinder-Bibliothek (abwärtskompatibel bis API-Level 21) eine weitere moderne Lösung. Dadurch wird die Anzeige des Kamerafeeds vereinfacht, da eine TextureView- oder SurfaceView-Klasse verwendet und alle erforderlichen Transformationen (Seitenverhältnis, Skalierung und Drehung) für Sie angewendet werden.

Weitere Informationen finden Sie im Blogpost Introducing Camera Viewfinder und im Entwicklerleitfaden Camera preview.

Lösung 3: Manuelle Camera2-Implementierung

Wenn Sie CameraX oder CameraViewfinder nicht verwenden können, müssen Sie die Ausrichtung und das Seitenverhältnis manuell berechnen und dafür sorgen, dass die Berechnungen bei jeder Konfigurationsänderung aktualisiert werden:

  • Die Ausrichtung des Kamerasensors (z. B. 0, 90, 180, 270 Grad) erhalten Sie über CameraCharacteristics.
  • Die aktuelle Bildschirmdrehung des Geräts abrufen (z. B. 0, 90, 180, 270 Grad).
  • Anhand dieser beiden Werte können Sie die erforderlichen Transformationen für Ihre SurfaceView oder TextureView ermitteln.
  • Achten Sie darauf, dass das Seitenverhältnis Ihres Ausgabebilds Surface mit dem Seitenverhältnis der Kameravorschau übereinstimmt, um Verzerrungen zu vermeiden.
  • Die Kamera-App wird möglicherweise in einem Teil des Bildschirms ausgeführt, entweder im Multi-Window- oder Desktop-Fenstermodus oder auf einem angeschlossenen Display. Daher sollte die Bildschirmgröße nicht verwendet werden, um die Abmessungen des Kamerasuchers zu bestimmen. Verwenden Sie stattdessen Fenstermesswerte.

Weitere Informationen finden Sie im Entwicklerleitfaden Kameravorschau und im Video Your Camera app on different form factors.

Lösung 4: Einfache Kameraaktionen mit einem Intent ausführen

Wenn Sie nicht viele Kamerafunktionen benötigen, ist es eine einfache und unkomplizierte Lösung, grundlegende Kameraaktionen wie das Aufnehmen eines Fotos oder Videos mit der Standardkameraanwendung des Geräts auszuführen. Sie müssen keine Integration in eine Kamerabibliothek vornehmen, sondern können stattdessen einen Intent verwenden.

Weitere Informationen finden Sie unter Kamera-Intents.

Konfiguration und Kontinuität

Faltbare Geräte bieten mehr Flexibilität bei der Benutzeroberfläche, können aber mehr Konfigurationsänderungen als nicht faltbare Geräte erfordern. Ihre App muss diese Konfigurationsänderungen und ihre Kombinationen verarbeiten können, z. B. das Drehen des Geräts, das Auf- und Zuklappen sowie das Anpassen der Fenstergröße im Mehrfenster- oder Desktopmodus. Dabei muss der App-Status beibehalten oder wiederhergestellt werden. Apps müssen beispielsweise folgende Kontinuität aufweisen:

  • App-Status ohne Abstürze oder störende Änderungen für Nutzer (z. B. beim Wechseln von Bildschirmen oder beim Senden der App in den Hintergrund)
  • Scrollposition von scrollbaren Feldern
  • In Textfelder eingegebener Text und Tastaturstatus
  • Wiedergabeposition der Medien, damit die Wiedergabe an der Stelle fortgesetzt wird, an der sie unterbrochen wurde, als die Konfigurationsänderung initiiert wurde

Zu den Konfigurationsänderungen, die häufig ausgelöst werden, gehören screenSize, smallestScreenSize, screenLayout, orientation, density, fontScale, touchscreen und keyboard.

Weitere Informationen finden Sie unter android:configChanges und Umgang mit Konfigurationsänderungen. Weitere Informationen zum Verwalten des App-Status finden Sie unter UI-Status speichern.

Änderungen an der Konfiguration des Kompaktheitsgrads

Das äußere und das innere Display von faltbaren Geräten mit drei Displays und faltbaren Geräten im Querformat haben möglicherweise unterschiedliche Pixeldichten. Daher ist beim Verwalten der Konfigurationsänderung für density besondere Aufmerksamkeit erforderlich. Unter Android wird die Aktivität in der Regel neu gestartet, wenn sich die Displaydichte ändert. Das kann zu Datenverlust führen. Damit das System die Aktivität nicht neu startet, deklarieren Sie die Dichtebehandlung in Ihrem Manifest und verwalten Sie die Konfigurationsänderung programmatisch in Ihrer App.

Konfiguration von AndroidManifest.xml

  • density: Gibt an, dass die App die Änderung der Bildschirmdichte verarbeitet.
  • Andere Konfigurationsänderungen: Es ist auch sinnvoll, andere häufig auftretende Konfigurationsänderungen anzugeben, z. B. screenSize, orientation, keyboardHidden, fontScale usw.

Wenn Sie die Dichte (und andere Konfigurationsänderungen) deklarieren, wird die Aktivität nicht neu gestartet, sondern onConfigurationChanged() aufgerufen.

Implementierung von onConfigurationChanged()

Wenn sich die Dichte ändert, müssen Sie Ihre Ressourcen im Callback aktualisieren, z. B. Bitmaps neu laden oder Layoutgrößen neu berechnen:

  • Prüfen Sie, ob die DPI in newConfig.densityDpi geändert wurden.
  • Benutzerdefinierte Ansichten, benutzerdefinierte Drawables usw. auf die neue Dichte zurücksetzen

Zu verarbeitende Ressourcenelemente

  • Bildressource: Ersetzen Sie Bitmaps und Drawables durch dichteabhängige Ressourcen oder passen Sie die Skalierung direkt an.
  • Layout-Einheit (Umrechnung von dp in px): Ansichtsgröße, Rand und Padding neu berechnen
  • Schriftart und Textgröße: Textgröße in sp-Einheiten neu anwenden
  • Benutzerdefiniertes Zeichnen von View/Canvas: Aktualisieren Sie die pixelbasierten Werte, die zum Zeichnen von Canvas verwendet werden.

App-Ausrichtung ermitteln

Verlassen Sie sich beim Erstellen adaptiver Apps niemals auf die physische Drehung des Geräts, da sie auf Geräten mit großen Displays ignoriert wird und eine App im Multi-Window-Modus eine andere Ausrichtung als das Gerät haben kann. Verwenden Sie stattdessen „Configuration.orientation“ oder „WindowMetrics“, um anhand der Fenstergröße zu ermitteln, ob Ihre App derzeit im Quer- oder Hochformat angezeigt wird.

Lösung 1: „Configuration.orientation“ verwenden

Mit dieser Property wird die Ausrichtung angegeben, in der Ihre App derzeit angezeigt wird.

Lösung 2: WindowMetrics#getBounds() verwenden

Sie können die aktuellen Anzeigegrenzen der App abrufen und ihre Breite und Höhe prüfen, um die Ausrichtung zu ermitteln.

Wenn Sie die Ausrichtung von Apps auf Smartphones (oder den äußeren Displays von Faltgeräten), aber nicht auf Geräten mit großen Displays einschränken möchten, lesen Sie den Abschnitt App-Ausrichtung auf Smartphones einschränken.

Positionen und Anzeigemodi

Faltbare Geräte unterstützen sowohl das Hoch- als auch das Querformat und können in verschiedenen Positionen verwendet werden, z. B. im Tischmodus und im HALF_OPENED-Modus. Trifolds unterstützen jedoch keine Aufstellung auf dem Tisch und können nicht HALF_OPENED verwendet werden. Faltbare Smartphones mit drei Displays bieten dagegen einen größeren Bildschirm und damit ein einzigartiges Nutzungserlebnis, wenn sie vollständig aufgeklappt sind.

Um Ihre App auf faltbaren Geräten zu differenzieren, die HALF_OPENED unterstützen, verwenden Sie Jetpack WindowManager-APIs wie FoldingFeature.

Weitere Informationen zu Faltpositionen, Status und Unterstützung für die Kameravorschau finden Sie in den folgenden Entwicklerleitfäden:

Faltbare Smartphones bieten ein einzigartiges Seherlebnis. Mit dem Modus für das Rückdisplay und dem Dual-Screen-Modus können Sie spezielle Displayfunktionen für faltbare Geräte entwickeln, z. B. eine Vorschau für Rückkamera-Selfies und die gleichzeitige, aber unterschiedliche Anzeige auf dem inneren und äußeren Display. Weitere Informationen finden Sie unter:

Ausrichtung an der natürlichen Sensorausrichtung ausrichten

Für sehr spezielle Anwendungsfälle, insbesondere Apps, die den gesamten Bildschirm unabhängig vom gefalteten Zustand des Geräts einnehmen müssen, können Sie mit dem Flag nosensor die App an die natürliche Ausrichtung des Geräts binden. Auf einem Pixel Fold ist die natürliche Ausrichtung des Geräts im zusammengeklappten Zustand beispielsweise das Hochformat, während sie im aufgeklappten Zustand das Querformat ist. Wenn Sie das Flag nosensor hinzufügen, wird die App auf dem äußeren Display im Hochformat und auf dem inneren Display im Querformat ausgeführt.

<activity
  android:name=".MainActivity"
  android:screenOrientation="nosensor">
Das nosensor-Flag führt nicht zu Problemen mit der App-Kompatibilität. Die Verwendung des Flags wird jedoch nicht empfohlen, da dies gegen die Richtlinien für adaptive Apps verstößt.

Spiele und Neuzuordnung von XR-Sensoren

Bei Spielen und XR-Apps werden Rohsensordaten (z. B. vom Gyroskop oder Beschleunigungsmesser) im gerätebezogenen Koordinatensystem bereitgestellt. Wenn der Nutzer das Gerät dreht, um ein Spiel im Querformat zu spielen, drehen sich die Sensorachsen nicht mit dem Bildschirm, was zu einer falschen Steuerung des Spiels führt.

Prüfen Sie zur Behebung dieses Problems die aktuelle Display.getRotation() und ordnen Sie die Achsen entsprechend neu zu:

  • Drehung 0: x=x, y=y
  • Drehung um 90°: x = –y, y=x
  • Rotation 180: x=-x, y=-y
  • Drehung um 270°: x=y, y=-x

Verwenden Sie für Rotationsvektoren (die in Kompass- oder XR-Apps verwendet werden) SensorManager.remapCoordinateSystem(), um die Richtung des Kameraobjektivs oder die Oberseite des Displays basierend auf der aktuellen Drehung den neuen Achsen zuzuordnen.

App-Kompatibilität

Apps müssen die Qualitätsrichtlinien für Apps einhalten, um die Kompatibilität mit allen Formfaktoren und angeschlossenen Displays zu gewährleisten. Wenn eine Anwendung die Richtlinien nicht einhalten kann, können Gerätehersteller Kompatibilitätsbehandlungen implementieren. Dies kann jedoch die Nutzerfreundlichkeit beeinträchtigen.

Weitere Informationen finden Sie in der umfassenden Liste der Kompatibilitäts-Workarounds auf der Plattform, insbesondere in den Abschnitten zu Kameravorschau, Überschreibungen und API-Änderungen für Android 16, die das Verhalten Ihrer App ändern könnten.

Weitere Informationen zum Erstellen adaptiver Apps finden Sie unter App-Qualität auf großen Bildschirmen.