Un'app multimediale in esecuzione su una TV deve consentire agli utenti di sfogliare le offerte di contenuti, effettuare una selezione e iniziare a riprodurre i contenuti. L'esperienza di navigazione dei contenuti per le app di questo tipo deve essere intuitiva, visivamente accattivante e coinvolgente.
I browser di cataloghi tendono a essere costituiti da diverse sezioni e ogni sezione ha un elenco di contenuti multimediali. Esempi di sezioni in un catalogo multimediale includono: playlist, contenuti in primo piano, categorie consigliate.
Utilizza le funzioni fornite da Compose per TV per implementare un'interfaccia utente per la navigazione di musica o video dal catalogo multimediale della tua app.
Creare una funzione componibile per il catalogo
Tutto ciò che viene visualizzato su uno schermo viene implementato come funzione componibile in Compose per TV. Inizia definendo una funzione componibile per il browser del catalogo multimediale:
@Composable fun CatalogBrowser( featuredContentList: List<Movie>, sectionList: List<Section>, modifier: Modifier = Modifier, onItemSelected: (Movie) -> Unit = {}, ) { // ToDo: add implementation }
CatalogBrowser è la funzione componibile che implementa il browser del catalogo multimediale. La funzione accetta i seguenti argomenti:
- Elenco dei contenuti in primo piano.
- Elenco delle sezioni.
- Un oggetto Modifier.
- Una funzione di callback che attiva una transizione dello schermo.
Impostare gli elementi UI
Compose per TV offre elenchi lazy, un componente per visualizzare un numero elevato di elementi (o un elenco di lunghezza sconosciuta). Chiama
LazyColumn
per posizionare le sezioni verticalmente. LazyColumn fornisce un
LazyListScope.() -> Unit
blocco che offre un DSL per definire i contenuti degli elementi. Nell'esempio seguente, ogni sezione viene inserita in un elenco verticale con uno spazio di 16 dp tra le sezioni:
@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) } } }
Nell'esempio, la funzione componibile SectionRow definisce come visualizzare le sezioni.
Nella funzione seguente, LazyRow mostra come questa
versione orizzontale di LazyColumn viene utilizzata in modo simile per
definire un elenco orizzontale con un blocco LazyListScope.() -> Unit chiamando
il DSL fornito:
@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) } ) } } }
Nel componibile SectionRow viene utilizzato il componente Text.
Il testo e altri componenti definiti in Material Design sono disponibili nella libreria tv-material . Puoi
modificare lo stile dei testi come definito in Material Design facendo riferimento all'oggetto
MaterialTheme.
Questo oggetto viene fornito anche dalla libreria tv-material.
Card fa parte della libreria tv-material.
MovieCard definisce come vengono visualizzati i dati di ogni film nel catalogo definito come il seguente snippet:
@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, ) } }
Evidenziare i contenuti in primo piano
Nell'esempio descritto in precedenza, tutti i film vengono visualizzati in modo uniforme.
Hanno la stessa area, senza differenze visive tra loro.
Puoi evidenziarne alcuni con Carousel.
Carousel mostra le informazioni in un insieme di elementi che possono scorrere, dissolversi o spostarsi nella visualizzazione. Utilizza il componente per evidenziare i contenuti in primo piano, come i film appena disponibili o i nuovi episodi dei programmi TV.
Carousel
prevede che tu specifichi almeno il numero di elementi che contiene e come disegnare ogni elemento. Il primo può essere specificato con itemCount. Il secondo può essere passato come lambda. Il numero di indice dell'elemento visualizzato viene fornito al lambda. Puoi determinare l'elemento visualizzato con il valore dell'indice specificato:
@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 può essere un elemento di un elenco lazy, ad esempio TvLazyColumn.
Il seguente snippet mostra il componibile FeaturedCarousel sopra tutti i componibili 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) } } }