Große, aufgeklappte Displays und einzigartige zugeklappte Zustände ermöglichen neue Nutzererlebnisse auf faltbaren Geräten. Wenn deine App in Jetpack Compose auf das Falten reagieren soll, verwende die Compose Material 3 Adaptive-Bibliothek. Sie bietet APIs für Fensterfunktionen faltbarer Geräte wie Falten, Scharniere und Gerätepositionen. Wenn deine App auf das Falten reagiert, kann sie ihr Layout so anpassen, dass wichtige Inhalte nicht im Bereich von Falten oder Scharnieren platziert werden. Falten und Scharniere können als natürliche Trennlinien verwendet werden.
Wenn du weißt, ob ein Gerät Konfigurationen wie die Tisch- oder Buchposition unterstützt, kannst du besser entscheiden, ob du verschiedene Layouts unterstützen oder bestimmte Funktionen anbieten möchtest.
Fensterinformationen
Verwende in Jetpack Compose die collectFoldingFeaturesAsState() zusammensetzbare
Funktion, um Informationen zum Falten des Fensters zu beobachten.
collectFoldingFeaturesAsState() erfasst die aktuellen Fensterfunktionen
von WindowInfoTracker in einem Compose-State, der eine Liste von
FoldingFeature-Objekten enthält.
Da collectFoldingFeaturesAsState() einen Compose-State zurückgibt, werden deine
zusammensetzbaren Funktionen automatisch neu zusammengesetzt, wenn sich der Faltzustand oder die Position des Geräts
ändert. Eine manuelle Lebenszyklusverwaltung oder Flow-Erfassung ist nicht erforderlich:
@Composable
fun FoldAwareScreen() {
val foldingFeatures by collectFoldingFeaturesAsState()
// Access folding features for the current window.
val foldFeature = foldingFeatures.firstOrNull()
if (foldFeature != null) {
// Adapt layout based on the fold feature.
}
}
Funktionen faltbarer Displays
Die Liste der FoldingFeature-Elemente, die von
collectFoldingFeaturesAsState() zurückgegeben werden (ein Untertyp von DisplayFeature)
enthält Informationen zu faltbaren Displays, einschließlich der folgenden
Attribute:
state: Der zugeklappte Zustand des Geräts,FLAToderHALF_OPENEDorientation: Die Ausrichtung der Falte oder des Scharniers,HORIZONTALoderVERTICALocclusionType: Gibt an, ob die Falte oder das Scharnier einen Teil des Displays verdeckt,NONEoderFULLisSeparating: Gibt an, ob die Falte oder das Scharnier zwei logische Anzeigebereiche erstellt, „true“ oder „false“
Bei einem faltbaren Gerät, das HALF_OPENED ist, wird isSeparating immer als „true“ gemeldet, da der Bildschirm in zwei Anzeigebereiche unterteilt ist. Außerdem ist isSeparating auf einem Gerät mit zwei Bildschirmen immer „true“, wenn die Anwendung beide Bildschirme umfasst.
Das Attribut FoldingFeature bounds (geerbt von DisplayFeature)
stellt das umgebende Rechteck einer Faltfunktion wie einer Falte oder eines Scharniers dar.
Mit den Grenzen können Elemente auf dem Bildschirm relativ zur Funktion positioniert werden:
@Composable
fun FoldFeatureDemo() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
if (foldFeature != null) {
val isSeparating = foldFeature.isSeparating
val occlusionType = foldFeature.occlusionType
val bounds = foldFeature.bounds
// Use bounds and properties to position content.
}
}
Tischposition
Mithilfe der Informationen im FoldingFeature-Objekt kann deine App Positionen wie die Tischposition unterstützen. Dabei liegt das Smartphone auf einer Oberfläche, das Scharnier befindet sich in horizontaler Position und der faltbare Bildschirm ist halb geöffnet.
Die Tischposition bietet Nutzern den Komfort, ihr Smartphone zu bedienen, ohne es in der Hand halten zu müssen. Die Tischposition eignet sich hervorragend zum Ansehen von Medien, Aufnehmen von Fotos und für Videoanrufe.
Verwende FoldingFeature.State und FoldingFeature.Orientation aus
collectFoldingFeaturesAsState(), um zu ermitteln, ob sich das Gerät in Tischposition befindet:
@Composable
fun TabletopContent() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
val isTableTopPosture = foldFeature != null &&
foldFeature.state == FoldingFeature.State.HALF_OPENED &&
foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
if (isTableTopPosture) {
// Tabletop layout: separate content and controls across the fold.
} else {
// Standard layout.
}
}
Alternativ kannst du prüfen, ob sich das Fenster in Tischposition befindet, indem du
das Posture Attribut überprüfst, das von
currentWindowAdaptiveInfoV2() zurückgegeben wird:
val adaptiveInfo = currentWindowAdaptiveInfoV2()
val isTabletop = adaptiveInfo.windowPosture.isTabletop
Sobald du weißt, dass sich das Gerät in Tischposition befindet, aktualisiere das Layout deiner App entsprechend. Bei Media-Apps bedeutet das in der Regel, dass die Wiedergabe oberhalb der Falte platziert wird und die Steuerelemente und zusätzlichen Inhalte direkt darunter positioniert werden, um eine freihändige Wiedergabe zu ermöglichen.
Beispiele
MediaPlayerActivity-App: Hier erfährst du, wie du mit Media3 ExoPlayer und WindowManager einen Videoplayer erstellen kannst, der auf das Falten reagiert.Codelab „Optimize your camera app on foldable devices with Jetpack WindowManager“: Hier erfährst du, wie du die Tischposition für Foto-Apps implementierst. Zeige den Sucher in der oberen Hälfte des Bildschirms („above the fold“ (ohne Scrollen sichtbar)) und die Steuerelemente in der unteren Hälfte an.
Buchposition
Eine weitere einzigartige Funktion faltbarer Geräte ist die Buchposition. Dabei ist das Gerät halb geöffnet und das Scharnier befindet sich in vertikaler Position. Die Buchposition eignet sich hervorragend zum Lesen von E‑Books. Mit einem zweiseitigen Layout auf einem großen faltbaren Bildschirm, der wie ein gebundenes Buch geöffnet ist, vermittelt die Buchposition das Gefühl, ein echtes Buch zu lesen.
Sie kann auch für die Fotografie verwendet werden, wenn du beim freihändigen Fotografieren ein anderes Seitenverhältnis aufnehmen möchtest.
Implementiere die Buchposition mit denselben Techniken wie die Tischposition. Prüfe, ob die Ausrichtung der Faltfunktion vertikal statt horizontal ist:
@Composable
fun BookContent() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
val isBookPosture = foldFeature != null &&
foldFeature.state == FoldingFeature.State.HALF_OPENED &&
foldFeature.orientation == FoldingFeature.Orientation.VERTICAL
if (isBookPosture) {
// Book posture layout: two-page layout across the vertical fold.
} else {
// Standard single-page layout.
}
}
Änderungen der Fenstergröße
Der Anzeigebereich einer App kann sich aufgrund einer Änderung der Gerätekonfiguration ändern, z. B. wenn das Gerät gefaltet oder aufgeklappt, gedreht oder im Mehrfenstermodus die Größe geändert wird.
Verwende in Jetpack
Compose die currentWindowAdaptiveInfoV2() zusammensetzbare Funktion aus
der Compose Material 3 Adaptive-Bibliothek, um die aktuelle Fenstergrößenklasse abzurufen und an Größenänderungen anzupassen. currentWindowAdaptiveInfoV2()
gibt eine WindowAdaptiveInfo-Instanz zurück, die die
WindowSizeClass des aktuellen Fensters (mit Unterstützung für große und
besonders große Breakpoints standardmäßig) sowie die
windowPosture des Geräts enthält:
@Composable
fun AdaptiveApp() {
val adaptiveInfo = currentWindowAdaptiveInfoV2()
val windowSizeClass = adaptiveInfo.windowSizeClass
when {
windowSizeClass.isWidthAtLeastBreakpoint(
WIDTH_DP_EXPANDED_LOWER_BOUND
) -> {
// Expanded layout
}
windowSizeClass.isWidthAtLeastBreakpoint(
WIDTH_DP_MEDIUM_LOWER_BOUND
) -> {
// Medium layout
}
else -> {
// Compact layout
}
}
}
Weitere Informationen findest du unter Fenstergrößenklassen verwenden.
Zusätzliche Ressourcen
Weitere Informationen zu Layouts, die auf das Falten reagieren, und zu faltbaren Geräten findest du in den folgenden Ressourcen:
Beispiele
- Jetpack WindowManager-Beispiel: Beispiel für die Verwendung der Jetpack WindowManager-Bibliothek
- Jetcaster : Implementierung der Tischposition mit Compose
Codelabs
- Programmieren für faltbare Smartphones und Geräte mit zwei Displays mit Jetpack WindowManager
- Optimize your camera app on foldable devices with Jetpack WindowManager