W przypadku aplikacji TV przeglądanie opiera się na wydajnej nawigacji opartej na zaznaczeniu. Korzystając ze standardowych leniwych układów Compose Foundation, możesz tworzyć wydajne listy pionowe i poziome, które automatycznie obsługują przewijanie sterowane zaznaczeniem, aby aktywne elementy były widoczne.
Domyślne przewijanie zoptymalizowane pod kątem telewizorów
Od wersji Compose Foundation 1.7.0 standardowe układy Lazy (takie jak LazyRow i LazyColumn) zawierają wbudowaną obsługę funkcji pozycjonowania zaznaczenia. Jest to zalecany sposób tworzenia katalogów dla aplikacji TV, ponieważ pomaga utrzymać zaznaczone elementy w widocznym miejscu i intuicyjnie je pozycjonować.
Aby zaimplementować podstawową listę przewijaną, użyj standardowych komponentów Lazy. Te komponenty automatycznie obsługują nawigację za pomocą pada kierunkowego i wyświetlają zaznaczony element.
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 */ } ) } } }
Dostosowywanie działania przewijania za pomocą BringIntoViewSpec
Jeśli Twój projekt wymaga określonego punktu „obrotu” (np. utrzymania elementu, na którym jest ustawiony fokus, dokładnie w odległości 30% od lewej krawędzi), możesz dostosować zachowanie przewijania za pomocą BringIntoViewSpec. Zastępuje to starszą funkcję pivotOffsets, umożliwiając dokładne określenie, jak widoczny obszar powinien się przewijać, aby pomieścić zaznaczony element.
1. Definiowanie niestandardowego elementu BringIntoViewSpec
Poniższy pomocniczy element kompozycyjny umożliwia zdefiniowanie „punktu obrotu” na podstawie ułamków nadrzędnych i podrzędnych. parentFraction określa, gdzie w kontenerze powinien znaleźć się element, a childFraction określa, która część elementu jest wyrównana z tym punktem.
@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. Zastosuj specyfikację niestandardową
Aby zastosować pozycjonowanie, opakuj układy za pomocą pomocnika. Jest to przydatne do tworzenia „spójnej linii ostrości” w różnych wierszach katalogu.
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. Rezygnacja z określonych zagnieżdżonych układów
Jeśli masz konkretny układ zagnieżdżony, który powinien używać standardowego przewijania zamiast niestandardowego przestawiania, podaj DefaultBringIntoViewSpec:
private val DefaultBringIntoViewSpec = object : BringIntoViewSpec {} PositionFocusedItemInLazyLayout { LazyColumn { item { // This row will ignore the custom pivot and use default behavior CompositionLocalProvider(LocalBringIntoViewSpec provides DefaultBringIntoViewSpec) { LazyRow { /* ... */ } } } } }
W efekcie przekazanie pustego BringIntoViewSpec umożliwia przejęcie kontroli przez działanie domyślne platformy.
Migracja z TV Foundation do Compose Foundation
Układy Lazy przeznaczone na telewizory w androidx.tv.foundation zostały wycofane na rzecz standardowych układów Compose Foundation.
Aktualizacje zależności
Sprawdź, czy build.gradle używa wersji 1.7.0 lub nowszej w przypadku:
androidx.compose.foundationandroidx.compose.runtime
Mapowanie komponentów
Aby przeprowadzić migrację, zaktualizuj importy i usuń prefiks Tv z komponentów:
| Wycofany komponent TV | Zamiennik Compose Foundation |
|---|---|
| TvLazyRow | LazyRow |
| TvLazyColumn | LazyColumn |
| TvLazyHorizontalGrid | LazyHorizontalGrid |
| TvLazyVerticalGrid | LazyVerticalGrid |
| pivotOffsets | BringIntoViewSpec (przez LocalBringIntoViewSpec) |