Pour les applications TV, l'expérience de navigation repose sur une navigation efficace basée sur la sélection. À l'aide des mises en page paresseuses Compose Foundation standards, vous pouvez créer des listes verticales et horizontales performantes qui gèrent automatiquement le défilement axé sur la sélection pour garder les éléments actifs visibles.
Comportement de défilement par défaut optimisé pour la TV
À partir de Compose Foundation 1.7.0, les mises en page standards à chargement différé (comme LazyRow et LazyColumn) incluent une compatibilité intégrée avec les fonctionnalités de positionnement de la mise au point. Il s'agit de la méthode recommandée pour créer des catalogues pour les applications TV, car elle permet de conserver les éléments sélectionnés visibles et positionnés de manière intuitive pour l'utilisateur.
Pour implémenter une liste déroulante de base, utilisez les composants lazy standards. Ces composants gèrent automatiquement la navigation au pavé directionnel et affichent l'élément sélectionné.
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 */ }
)
}
}
}
Personnaliser le comportement de défilement avec BringIntoViewSpec
Si votre conception nécessite un point de "pivot" spécifique (par exemple, en gardant l'élément sélectionné exactement à 30 % du bord gauche), vous pouvez personnaliser le comportement de défilement à l'aide d'un BringIntoViewSpec. Cela remplace l'ancienne fonctionnalité pivotOffsets en vous permettant de définir précisément comment la fenêtre d'affichage doit défiler pour s'adapter à un élément sélectionné.
1. Définir un BringIntoViewSpec personnalisé
Le composable d'assistance suivant vous permet de définir un "pivot" en fonction des fractions parent et enfant. parentFraction détermine l'emplacement de l'élément dans le conteneur, tandis que childFraction détermine la partie de l'élément qui s'aligne sur ce point.
@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. Appliquer la spécification personnalisée
Encapsulez vos mises en page avec l'assistant pour appliquer le positionnement. Cela est utile pour créer une "ligne de mise au point cohérente" sur différentes lignes de votre catalogue.
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. Désactiver des mises en page imbriquées spécifiques
Si vous avez une mise en page imbriquée spécifique qui doit utiliser le comportement de défilement standard au lieu de votre pivot personnalisé, fournissez 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 { ... }
}
}
}
}
En effet, en transmettant un BringIntoViewSpec vide, vous permettez au comportement par défaut du framework de prendre le relais.
Migration de TV Foundation vers Compose Foundation
Les mises en page différées spécifiques à la TV dans androidx.tv.foundation sont obsolètes au profit des mises en page Compose Foundation standards.
Mises à jour des dépendances
Vérifiez que votre build.gradle utilise la version 1.7.0 ou ultérieure pour :
androidx.compose.foundationandroidx.compose.runtime
Mappage des composants
Pour effectuer la migration, mettez à jour vos importations et supprimez le préfixe Tv de vos composants :
| Composant TV obsolète | Remplacement de Compose Foundation |
|---|---|
| TvLazyRow | LazyRow |
| TvLazyColumn | LazyColumn |
| TvLazyHorizontalGrid | LazyHorizontalGrid |
| TvLazyVerticalGrid | LazyVerticalGrid |
| pivotOffsets | BringIntoViewSpec (via LocalBringIntoViewSpec) |