Une application multimédia qui s'exécute sur un téléviseur doit permettre aux utilisateurs de parcourir son offre de contenu, de faire une sélection et de lancer la lecture du contenu. L'expérience de navigation dans le contenu des applications de ce type doit être intuitive, visuellement agréable et engageante.
Les navigateurs de catalogue se composent généralement de plusieurs sections, chacune contenant une liste de contenus multimédias. Voici quelques exemples de sections dans un catalogue multimédia : playlists, sélection de contenus, catégories recommandées.
Utilisez les fonctions fournies par Compose pour TV afin d'implémenter une interface utilisateur permettant de parcourir la musique ou les vidéos du catalogue multimédia de votre application.
Créer une fonction composable pour le catalogue
Tout ce qui s'affiche à l'écran est implémenté en tant que fonction composable dans Compose pour TV. Commencez par définir une fonction composable pour le navigateur de catalogue multimédia :
@Composable fun CatalogBrowser( featuredContentList: List<Movie>, sectionList: List<Section>, modifier: Modifier = Modifier, onItemSelected: (Movie) -> Unit = {}, ) { // ToDo: add implementation }
CatalogBrowser est la fonction composable qui implémente votre navigateur de catalogue multimédia. La fonction utilise les arguments suivants :
- Liste des contenus mis en avant.
- Liste des sections.
- Objet Modifier.
- Une fonction de rappel qui déclenche une transition d'écran.
Définir des éléments d'interface utilisateur
Compose pour TV propose des listes "lazy", un composant permettant d'afficher un grand nombre d'éléments (ou une liste d'une longueur indéterminée). Appelez LazyColumn pour placer les sections verticalement. LazyColumn fournit un bloc LazyListScope.() -> Unit qui propose un DSL permettant de définir le contenu des éléments. Dans l'exemple suivant, chaque section est placée dans une liste verticale avec un espace de 16 dp entre les sections :
@Composable fun CatalogBrowser( featuredContentList: List<Movie>, sectionList: List<Section>, modifier: Modifier = Modifier, onItemSelected: (Movie) -> Unit = {}, ) { LazyColumn( modifier = modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(16.dp) ) { items(sectionList.size) { index -> val section = sectionList[index] SectionRow(section, onItemSelected = onItemSelected) } } }
Dans l'exemple, la fonction composable SectionRow définit la façon d'afficher les sections.
Dans la fonction suivante, LazyRow montre comment cette version horizontale de LazyColumn est utilisée de la même manière pour définir une liste horizontale avec un bloc LazyListScope.() -> Unit en appelant le DSL fourni :
@Composable fun SectionRow( section: Section, modifier: Modifier = Modifier, onItemSelected: (Movie) -> Unit = {}, ) { Text( text = section.title, style = MaterialTheme.typography.headlineSmall, ) MovieCatalog( section.movieList, onClick = { movie -> onItemSelected(movie) }, modifier ) }
@Composable fun MovieCatalog( movies: List<Movie>, onClick: (Movie) -> Unit, modifier: Modifier = Modifier, ) { LazyRow( modifier = modifier, horizontalArrangement = Arrangement.spacedBy(8.dp) ) { items(movies.size) { index -> val movie = movies[index] MovieCard( movie = movie, onClick = { onClick(movie) } ) } } }
Le composant Text est utilisé dans le composable SectionRow.
Le texte et les autres composants définis dans Material Design sont proposés dans la bibliothèque tv-material . Vous pouvez modifier le style des textes tel qu'il est défini dans Material Design en vous référant à l'objet MaterialTheme.
Cet objet est également fourni par la bibliothèque tv-material.
Card fait partie de la bibliothèque tv-material.
MovieCard définit la façon dont chaque donnée de film est affichée dans le catalogue, comme indiqué dans l'extrait de code suivant :
@OptIn(ExperimentalMaterial3Api::class) @Composable fun MovieCard( movie: Movie, modifier: Modifier = Modifier, onClick: () -> Unit = {} ) { Card( modifier = modifier, onClick = onClick ) { AsyncImage( model = movie.thumbnailUrl, contentDescription = movie.title, ) } }
Mettre en avant une sélection de contenus
Dans l'exemple décrit précédemment, tous les films sont affichés de manière égale.
Elles ont la même superficie et ne présentent aucune différence visuelle.
Vous pouvez en mettre en évidence certains avec Carousel.
Le carrousel affiche les informations dans un ensemble d'éléments qui peuvent glisser, s'estomper ou se déplacer pour être visibles. Vous utilisez le composant pour mettre en avant des sélections de contenus, comme des films ou des épisodes de séries TV récemment disponibles.
Carousel s'attend à ce que vous spécifiiez au moins le nombre d'éléments que contient le carrousel et la manière de dessiner chaque élément. Le premier peut être spécifié avec itemCount. La seconde peut être transmise en tant que lambda. Le numéro d'index de l'élément affiché est transmis au lambda. Vous pouvez déterminer l'élément affiché avec la valeur d'index donnée :
@OptIn(ExperimentalTvMaterial3Api::class) @Composable fun FeaturedCarousel( featuredContentList: List<Movie>, modifier: Modifier = Modifier, ) { Carousel( itemCount = featuredContentList.size, modifier = modifier, ) { index -> val content = featuredContentList[index] Box { AsyncImage( model = content.backgroundImageUrl, contentDescription = content.description, placeholder = painterResource( id = R.drawable.movie_placeholder ), contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize() ) Text(text = content.title) } } }
Carousel peut être un élément d'une liste différée, comme LazyColumn.
L'extrait de code suivant montre le composable FeaturedCarousel au-dessus de tous les composables SectionRow :
@OptIn(ExperimentalTvMaterial3Api::class) @Composable fun CatalogBrowser( featuredContentList: List<Movie>, sectionList: List<Section>, modifier: Modifier = Modifier, onItemSelected: (Movie) -> Unit = {}, ) { LazyColumn( modifier = modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(16.dp) ) { item { FeaturedCarousel(featuredContentList) } items(sectionList) { section -> SectionRow(section, onItemSelected = onItemSelected) } } }