Per le app TV, l'esperienza di navigazione si basa su una navigazione efficiente basata sulla messa a fuoco. Utilizzando i layout pigri standard di Compose Foundation, puoi creare elenchi verticali e orizzontali efficienti che gestiscono automaticamente lo scorrimento basato sulla messa a fuoco per mantenere in vista gli elementi attivi.
Comportamento di scorrimento predefinito ottimizzato per la TV
A partire da Compose Foundation 1.7.0, i layout pigri standard (come LazyRow
e LazyColumn) includono il supporto integrato per le funzionalità di posizionamento della messa a fuoco. Questo
è il modo consigliato per creare cataloghi per le app TV, in quanto consente di mantenere visibili e posizionati in modo intuitivo per l'utente gli elementi
su cui si concentra.
Per implementare un elenco di base scorrevole, utilizza i componenti pigri standard. Questi componenti gestiscono automaticamente la navigazione tramite D-pad e portano l'elemento selezionato in primo piano.
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 */ } ) } } }
Personalizzare il comportamento di scorrimento con BringIntoViewSpec
Se il tuo design richiede un punto di "pivot" specifico (ad esempio, mantenere l'elemento
focalizzato esattamente al 30% dal bordo sinistro), puoi personalizzare il comportamento di scorrimento
utilizzando un BringIntoViewSpec. Questa funzionalità sostituisce la precedente pivotOffsets
consentendoti di definire esattamente come deve scorrere la finestra
per adattarsi a un elemento selezionato.
1. Definisci un BringIntoViewSpec personalizzato
Il seguente composable helper consente di definire un "pivot" in base alle frazioni padre e figlio. parentFraction determina il punto del contenitore in cui deve essere posizionato l'elemento, mentre childFraction determina la parte dell'elemento che si allinea a quel punto.
@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. Applica la specifica personalizzata
Racchiudi i layout con l'helper per applicare il posizionamento. Questa funzionalità è utile per creare una "linea di messa a fuoco coerente" in diverse righe del catalogo.
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. Disattivazione per layout nidificati specifici
Se hai un layout nidificato specifico che deve utilizzare il comportamento di scorrimento standard
anziché il pivot personalizzato, fornisci 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 { /* ... */ } } } } }
In effetti, passando un BringIntoViewSpec vuoto, il comportamento predefinito del framework viene ripristinato.
Migrazione da TV Foundation a Compose Foundation
I layout pigri specifici per la TV in androidx.tv.foundation sono ritirati a favore
dei layout standard di Compose Foundation.
Aggiornamenti delle dipendenze
Verifica che build.gradle utilizzi la versione 1.7.0 o successive per:
androidx.compose.foundationandroidx.compose.runtime
Mappatura dei componenti
Per eseguire la migrazione, aggiorna le importazioni e rimuovi il prefisso Tv dai componenti:
| Componente TV ritirato | Componi la sostituzione di Fondazione |
|---|---|
| TvLazyRow | LazyRow |
| TvLazyColumn | LazyColumn |
| TvLazyHorizontalGrid | LazyHorizontalGrid |
| TvLazyVerticalGrid | LazyVerticalGrid |
| pivotOffsets | BringIntoViewSpec (tramite LocalBringIntoViewSpec) |