Jetpack-Fenster-Manager für faltbare Geräte
Der Jetpack-Fenster-Manager stellt eine Standard-API für die Arbeit mit allen faltbaren Geräten bereit. Sie enthält zwei wichtige Klassen:
- DisplayFeature: Erkennt Unterbrechungen der fortlaufenden flachen Bildschirmoberfläche wie Scharniere oder Faltungen. Der Fenster-Manager gibt eine Sammlung von Anzeigefeatures aus einem Rückruf für Layoutänderungen zurück.
- FoldingFeature: Bietet Informationen zu einem bestimmten Feature des Geräts. Surface Duo weist nur ein Faltfeature auf, es ist aber möglich, dass andere Geräte mehr bieten.
Ein ähnlicher Leitfaden befindet sich im Android Foldable Codelab. Weitere Informationen zum Entwickeln für faltbare Geräte finden Sie in der Android-Dokumentation. Beispiele vom Android-Team sind auch auf GitHub verfügbar. In den Jetpack-Versionshinweisen werden Änderungen im Fenster-Manager erfasst, wenn er aktualisiert wird.
Tipp
Die Steuerelemente und Hilfsklassen in der Surface Duo-Doppelbildschirm-Bibliothek funktionieren mit dem Fenster-Manager. Folgen Sie den Anweisungen, um Ihrem App-Projekt die richtigen Pakete hinzuzufügen.
Befolgen Sie die Anweisungen unten, um den Fenster-Manager direkt in Ihrem Code zu verwenden:
Hinzufügen von Abhängigkeiten
Achten Sie darauf, das
mavenCentral()
-Repository in Ihre build.gradle-Datei der obersten Ebene aufzunehmen:allprojects { repositories { google() mavenCentral() } }
Vergewissern Sie sich, dass die
compileSdkVersion
undtargetSdkVersion
in Ihrer build.gradle-Datei auf Modulebene auf API 31 oder neuer festgelegt sind:android { compileSdkVersion 31 defaultConfig { targetSdkVersion 31 } ... }
Fügen Sie Ihrer build.gradle-Datei auf Modulebene die folgenden Abhängigkeiten hinzu:
Verwenden des Fenster-Managers in Ihrem Kotlin-Code
Beim Zugriff auf die Fenster-Manager-Eigenschaften in Ihren Kotlin-Projekten ist es wichtig, den richtigen Informationsfluss einzurichten. Andernfalls empfangen Sie möglicherweise zu wenige oder zu viele Ereignisupdates, und die App-Leistung könnte beeinträchtigt sein.
Führen Sie die Schritte unten aus, um ein WindowInfoTracker
-Objekt zu initialisieren und zu verwenden:
Erstellen Sie in Ihrer MainActivity-Klasse eine Variable für den
WindowInfoTracker
. Achten Sie darauf, dass oben in der Dateiimport androidx.window.layout.WindowInfoTracker
hinzugefügt wird.class MainActivity : AppCompatActivity() { private lateinit var windowInfoTracker: WindowInfoTracker
Initialisieren Sie den
WindowInfoTracker
in deronCreate
-Methode Ihrer Aktivität, und richten Sie einen Flow ein, um Informationen aus derwindowLayoutInfo
-Eigenschaft zu erfassen.override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialize the window manager windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) // Set up a flow lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowInfoTracker.windowLayoutInfo(this@MainActivity) .collect { // Check FoldingFeature properties here } } } }
Achten Sie darauf, dass diese Importe ebenfalls am Anfang der Datei hinzugefügt werden:
import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch
Fügen Sie Code hinzu, um den
WindowLayoutInfo
-Flow auf Eigenschaften des Faltfeatures zu prüfen. Beim Ausführen dieses Codes wird die Aktivität mit der aktuellen Geräteposition und den Anzeigefeatures aktualisiert (im Fall einer ein Scharnier oder eine Faltung überspannenden Darstellung).Im nachstehenden Codeausschnitt zeigt die Aktivität unterschiedlichen Text basierend auf den Eigenschaften eines
FoldingFeature
an.Dieses Beispiel enthält eine TextView mit dem Namen
layout_change_text
, die den Okklusionstyp und denisSeparating
-Wert für alle erkannten Faltfeatures angibt.override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowInfoTracker.windowLayoutInfo(this@MainActivity) .collect { newLayoutInfo -> layout_change_text.text = "No display features detected" for (displayFeature : DisplayFeature in newLayoutInfo.displayFeatures) { if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.NONE) { layout_change_text.text = "App is spanned across a fold, " + "isSeparating = ${displayFeature.isSeparating}" } if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.FULL) { layout_change_text.text = "App is spanned across a hinge, " + "isSeparating = ${displayFeature.isSeparating}" } } } } } }
Faltfeature-Eigenschaften
Die Klasse WindowLayoutInfo
enthält eine Sammlung von DisplayFeature
-Elementen, von denen eins oder mehrere möglicherweise Instanzen der FoldingFeature-Klasse sind.
Faltfeatures weisen die folgenden Eigenschaften auf:
bounds
: Koordinaten des Begrenzungsrechtecks eines FaltfeaturesocclusionType
: wenn ein Faltfeature Inhalte ausblendet (FULL
oderNONE
)orientation
: Ausrichtung eines Faltfeatures (HORIZONTAL
oderVERTICAL
)state
: Winkel eines Faltfeatures (HALF_OPENED
oderFLAT
)isSeparating
: wenn ein Faltfeature den Anzeigebereich in zwei verschiedene Abschnitte trennt
Sie können diese Eigenschaften abfragen, um Entscheidungen darüber zu treffen, wie Sie Ihr Layout nach Konfigurationsänderungen anpassen.
isSeparating
Sie verwenden die IsSeparating-Eigenschaft, um zu entscheiden, wo Steuerelemente angezeigt oder wie viele Inhaltsbereiche verwendet werden sollen. Dieses Feld stellt sicher, dass Ihre App auf allen faltbaren Geräten die optimale Benutzererfahrung bietet:
- Bei Geräten mit Doppelbildschirm ist sie immer TRUE, wenn eine App das Scharnier übergreifend dargestellt wird
- Bei anderen faltbaren Geräten ist sie nur dann TRUE, wenn der Status
HALF_OPENED
ist, etwa wenn sich ein Gerät in der Tabletop-Position befindet
Verwenden Sie die isSeparating
-Eigenschaft, um festzulegen, ob bei einer Darstellung ohne Trennung das Layout der Benutzeroberfläche für ein faltbares Gerät angepasst oder das Standardlayout verwendet werden soll:
private fun updateCurrentLayout(newLayoutInfo: WindowLayoutInfo) {
for (displayFeature in newLayoutInfo.displayFeatures) {
val foldFeature = displayFeature as? FoldingFeature
foldFeature?.let {
if (it.isSeparating) {
// The content is separated by the FoldingFeature.
// Here is where you should adapt your UI.
} else {
// The content is not separated.
// Users can see and interact with your UI properly.
}
}
}
}
Ein ausführlicheres Beispiel zur Verwendung dieses Felds findet sich in diesem isSeparating-Beispiel.
Google bietet ebenfalls Dokumentationen und Beispiele im Zusammenhang mit dieser Eigenschaft im Rahmen seiner Anleitungen für große Bildschirme und faltbare Geräte.
Beispiele
Das Repository surface-duo-jetpack-window-manager-samples auf GitHub enthält eine Reihe von Kotlin-Beispielen, die verschiedene Muster für die Dual-Screen-Benutzererfahrung veranschaulichen, die mit dem Jetpack-Fenster-Manager und dem herkömmlichen Darstellungssystem erstellt wurden.
Das GitHub-Repository surface-duo-compose-samples enthält außerdem Kotlin-Beispiele für Doppelbildschirmgeräte, die den Jetpack-Fenster-Manager verwenden, doch wird in diesen Beispielen die Benutzeroberfläche mit Jetpack Compose erstellt.
Java-API
Lesen Sie den Blogbeitrag Jetpack Window Manager with Java (Jetpack-Fenster-Manager mit Java) und dieses Java-Beispiel, um zu erfahren, wie Sie über WindowInfoTrackerCallbackAdapter
auf die WindowInfoTracker
-Klasse zugreifen.