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 Anwendungen für faltbare Geräte erstellen, insbesondere für Geräte wie das Samsung Trifold oder das ursprüngliche Pixel Fold, die im Querformat geöffnet werden (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 Innendisplay nicht überein (Annahmen basieren auf rotation_0 = Hochformat). Dadurch schlagen Apps beim Auf- und Zuklappen fehl.
  • 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, sollten Sie sich 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.
  • Kameravorschaubilder aktualisieren, um Geräteausrichtung und Seitenverhältnisse korrekt zu verwalten, seitlich gedrehte Vorschaubilder 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 Neustarts der App oder Statusverluste zu vermeiden.
  • Bei Apps, die Bewegungssensoren verwenden, muss das Koordinatensystem an die aktuelle Ausrichtung des Displays angepasst werden. Außerdem sollten keine Annahmen auf Grundlage von „rotation_0 = Hochformat“ getroffen werden, um präzise Nutzerinteraktionen zu gewährleisten.

Adaptiv erstellen

Wenn Ihre App bereits adaptiv ist und dem in den Qualitätsrichtlinien für adaptive Apps beschriebenen optimierten Level (Tier 2) entspricht, sollte sie auf faltbaren Geräten gut funktionieren. Andernfalls sollten Sie sich die folgenden grundlegenden Android-Konzepte für die adaptive Entwicklung ansehen, bevor Sie die spezifischen Details von faltbaren Geräten mit drei Displays und faltbaren Geräten im Querformat prü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 Mehrfenster- oder Desktop-Fenstermodus. Weitere Informationen zu adaptiven Layouts

  • Adaptive Layouts entwerfen und implementieren
  • Primäre Navigation der App an die Fenstergröße anpassen
  • UI der App mit Fenstergrößenklassen anpassen
  • Die Implementierung kanonischer Layouts wie Listen- und Detailansichten mit den Jetpack-APIs vereinfachen
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

Auf faltbaren Geräten, einschließlich faltbarer Geräte im Querformat und Trifolds, kann sofort zwischen den Fenstergrößenklassen „Kompakt“, „Mittel“ und „Erweitert“ gewechselt werden. Wenn Sie diese Klassen verstehen und implementieren, werden in Ihrer App die richtigen Navigationskomponenten und die richtige Inhaltsdichte 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 die Fenstergröße.

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()
val windowSizeClass = adaptiveInfo.windowSizeClass

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

Weitere Informationen finden Sie unter Fenstergrößenklassen verwenden.

Adaptive App-Qualität

Wenn Sie die Qualitätsrichtlinien für adaptive Apps der Stufe 2 (Adaptive App, optimiert) oder Stufe 1 (Adaptive App, differenziert) einhalten, bietet Ihre App eine überzeugende 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 Stufen, um von einer adaptiven zu einer differenzierten Nutzung zu gelangen.

Android 16 und 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 Trifolds und faltbaren Geräten im Querformat gibt es besondere 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 dem Multi-Window-Modus, dem Desktop-Freiform-Fenster oder bei verbundenen Displays) ist, dass 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 Faltgerä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 fälschlicherweise gedreht oder skaliert wird. Das kann auch 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 (empfohlen)

Die einfachste und stabilste Lösung ist die Verwendung der Jetpack CameraX-Bibliothek. Das PreviewView-UI-Element wurde entwickelt, um alle Vorschaukomplexitäten 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 (Vorschau implementieren).

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 TextureView oder SurfaceView 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) kann aus CameraCharacteristics abgerufen werden.
  • 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 SurfaceView oder TextureView ermitteln.
  • Achten Sie darauf, dass das Seitenverhältnis Ihrer Ausgabe 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-Freiform-Fenster-Modus 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 (Ihre Kamera-App auf verschiedenen Formfaktoren).

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

Wenn Sie nicht viele Kamerafunktionen benötigen, können Sie grundlegende Kameraaktionen wie das Aufnehmen von Fotos oder Videos mit der Standardkamera-App des Geräts ausführen. Sie müssen keine Kamerabibliothek einbinden, 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 auslösen. 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, während der App-Status beibehalten oder wiederhergestellt wird. 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 stattdessen onConfigurationChanged() aufgerufen.

onConfigurationChanged()-Implementierung

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 sich die DPI in newConfig.densityDpi geändert haben.
  • 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 Innenabstand neu berechnen
  • Schriftart und Textgröße: Textgröße in sp-Einheiten neu anwenden
  • Benutzerdefinierte View-/Canvas-Darstellung: 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 Mehrfenstermodus 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 im Hoch- und Querformat unterstützen sowohl den Tischmodus als auch den 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, die HALF_OPENED unterstützen, zu differenzieren, 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 Geräte bieten einzigartige Möglichkeiten für die Videowiedergabe. Mit dem Modus für das äußere Display und dem Dual-Screen-Modus können Sie spezielle Displayfunktionen für faltbare Geräte entwickeln, z. B. eine Vorschau für Selfies mit der Rückkamera 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 immer im Hochformat und auf dem inneren Display immer im Querformat ausgeführt.

<activity
  android:name=".MainActivity"
  android:screenOrientation="nosensor">

Spiele und Neuzuordnung von XR-Sensoren

Bei Spielen und XR-Apps werden rohe Sensordaten (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 Display, was zu einer falschen Spielsteuerung 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
  • 180°-Drehung: 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.

Eine umfassende Liste der Kompatibilitäts-Workarounds, die auf der Plattform bereitgestellt werden, finden Sie dort. Achten Sie insbesondere auf die Workarounds für 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 in den Qualitätsrichtlinien für adaptive Apps.