Bei TV-Apps basiert die Navigation auf einem effizienten Fokus. Mit den standardmäßigen Lazy-Layouts von Compose Foundation können Sie leistungsstarke vertikale und horizontale Listen erstellen, bei denen das fokussierte Scrollen automatisch erfolgt, damit aktive Elemente im Blick bleiben.
Standardmäßiges Scrollverhalten für die TV-Wiedergabe optimiert
Ab Compose Foundation 1.7.0 bieten standardmäßige Lazy-Layouts (z. B. LazyRow und LazyColumn) integrierte Unterstützung für Funktionen zur Fokuspositionierung. Dies ist die empfohlene Methode zum Erstellen von Katalogen für TV-Apps, da sie dazu beiträgt, dass fokussierte Elemente sichtbar bleiben und intuitiv für den Nutzer positioniert werden.
Verwenden Sie die standardmäßigen Lazy-Komponenten, um eine einfache scrollbare Liste zu implementieren. Diese Komponenten übernehmen automatisch die Navigation mit dem Steuerkreuz und bringen das fokussierte Element in den sichtbaren Bereich.
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items @Composable fun MovieCatalog(movies: List<Movie>) { LazyRow { items(movies) { movie -> MovieCard( movie = movie, onClick = { /* Handle click */ } ) } } }
Scrollverhalten mit BringIntoViewSpec anpassen
Wenn Ihr Design einen bestimmten „Drehpunkt“ erfordert, z. B. wenn das fokussierte Element genau 30% vom linken Rand entfernt sein soll, können Sie das Scrollverhalten mit einem BringIntoViewSpec anpassen. Diese Funktion ersetzt die alte pivotOffsets-Funktion und ermöglicht es Ihnen, genau festzulegen, wie der Viewport scrollen soll, um ein fokussiertes Element zu berücksichtigen.
1. Benutzerdefiniertes BringIntoViewSpec definieren
Mit dem folgenden Helper-Composable können Sie einen „Pivot“ basierend auf den Anteilen von übergeordnetem und untergeordnetem Element definieren. Mit parentFraction wird festgelegt, wo im Container das Element platziert werden soll, und mit childFraction wird bestimmt, welcher Teil des Elements an diesem Punkt ausgerichtet wird.
@OptIn(ExperimentalFoundationApi::class) @Composable fun PositionFocusedItemInLazyLayout( parentFraction: Float = 0.3f, childFraction: Float = 0f, content: @Composable () -> Unit, ) { val bringIntoViewSpec = remember(parentFraction, childFraction) { object : BringIntoViewSpec { override fun calculateScrollDistance( offset: Float, // Item's initial position size: Float, // Item's size containerSize: Float // Container's size ): Float { // Calculate the offset position of the item's leading edge. val initialTargetForLeadingEdge = parentFraction * containerSize - (childFraction * size) // If the item fits in the container, and scrolling would cause // its trailing edge to be clipped, adjust targetForLeadingEdge // to prevent over-scrolling near the end of list. val targetForLeadingEdge = if (size <= containerSize && (containerSize - initialTargetForLeadingEdge) < size) { // If clipped, align the item's trailing edge with the // container's trailing edge. containerSize - size } else { initialTargetForLeadingEdge } // Return scroll distance relative to initial item position. return offset - targetForLeadingEdge } } } // Apply the spec to all scrollables in the hierarchy CompositionLocalProvider( LocalBringIntoViewSpec provides bringIntoViewSpec, content = content, ) }
2. Benutzerdefinierte Spezifikation anwenden
Umschließen Sie Ihre Layouts mit dem Helfer, um die Positionierung anzuwenden. Das ist nützlich, um in verschiedenen Zeilen Ihres Katalogs eine „einheitliche Fokuslinie“ zu erstellen.
PositionFocusedItemInLazyLayout( parentFraction = 0.3f, // Pivot 30% from the edge childFraction = 0.5f // Center of the item aligns with the pivot ) { LazyColumn { items(sectionList) { section -> // This row and its items will respect the 30% pivot LazyRow { /* ... */ } } } }
3. Bestimmte verschachtelte Layouts deaktivieren
Wenn Sie ein bestimmtes verschachteltes Layout haben, das das Standard-Scrollverhalten anstelle Ihres benutzerdefinierten Pivots verwenden soll, geben Sie DefaultBringIntoViewSpec an:
private val DefaultBringIntoViewSpec = object : BringIntoViewSpec {} PositionFocusedItemInLazyLayout { LazyColumn { item { // This row will ignore the custom pivot and use default behavior CompositionLocalProvider(LocalBringIntoViewSpec provides DefaultBringIntoViewSpec) { LazyRow { /* ... */ } } } } }
Wenn Sie ein leeres BringIntoViewSpec übergeben, wird das Standardverhalten des Frameworks übernommen.
Migration von TV Foundation zu Compose Foundation
Die fernseherspezifischen Lazy-Layouts in androidx.tv.foundation sind zugunsten der Standard-Compose Foundation-Layouts veraltet.
Abhängigkeitsupdates
Prüfen Sie, ob für Ihr build.gradle Version 1.7.0 oder höher verwendet wird für:
androidx.compose.foundationandroidx.compose.runtime
Komponentenzuordnung
Aktualisieren Sie zum Migrieren Ihre Importe und entfernen Sie das Präfix Tv aus Ihren Komponenten:
| Eingestellte TV-Komponente | Compose Foundation-Ersatz |
|---|---|
| TvLazyRow | LazyRow |
| TvLazyColumn | LazyColumn |
| TvLazyHorizontalGrid | LazyHorizontalGrid |
| TvLazyVerticalGrid | LazyVerticalGrid |
| pivotOffsets | BringIntoViewSpec (über LocalBringIntoViewSpec) |