Creare un browser del catalogo

Un'app multimediale eseguita su una TV deve consentire agli utenti di sfogliare le offerte di contenuti, effettuare una selezione e avviare la riproduzione dei contenuti. L'esperienza di navigazione dei contenuti per le app di questo tipo deve essere intuitiva, visivamente piacevole e coinvolgente.

I browser dei cataloghi tendono a essere costituiti da diverse sezioni e ogni sezione ha un elenco di contenuti multimediali. Esempi di sezioni di un catalogo multimediale includono: playlist, contenuti in primo piano, categorie consigliate.

Figura 1. Schermata tipica del catalogo. Gli utenti possono sfogliare i dati del catalogo video.

Utilizza le funzioni fornite da Compose for TV per implementare un'interfaccia utente per sfogliare musica o video dal catalogo multimediale della tua app.

Crea una funzione componibile per il catalogo

Tutto ciò che viene visualizzato su un display viene implementato come funzione componibile in Compose for 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 di contenuti in primo piano.
  • Elenco delle sezioni.
  • Un oggetto Modifier.
  • Una funzione di callback, che attiva una transizione della schermata.

Imposta gli elementi UI

Compose for 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 blocco LazyListScope.() -> Unit, che offre un DSL per definire i contenuti degli elementi. Nell'esempio seguente, ogni sezione è 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 gli altri componenti definiti in Material Design sono offerti nella libreria tv-material . Puoi modificare lo stile dei testi come definito in Material Design facendo riferimento all'oggetto MaterialTheme. Questo oggetto è fornito anche dalla libreria tv-material. Card fa parte della libreria tv-material. MovieCard definisce il modo in cui i dati di ogni film vengono visualizzati nel catalogo definito come lo snippet seguente:

@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,
        )
    }
}

Nell'esempio descritto in precedenza, tutti i film vengono visualizzati allo stesso modo. Hanno la stessa area, non c'è alcuna differenza visiva tra loro. Puoi metterne in evidenza alcune con Carousel.

Il carosello mostra le informazioni in un insieme di elementi che possono scorrere, dissolversi o spostarsi nella visualizzazione. Utilizza il componente per mettere in evidenza i contenuti in primo piano, ad esempio film appena resi disponibili o nuove puntate di programmi TV.

Carousel si aspetta che tu specifichi almeno il numero di elementi presenti nel carosello e come disegnare ogni elemento. Il primo può essere specificato con itemCount. Il secondo può essere passato come funzione lambda. Il numero di indice dell'elemento visualizzato viene assegnato alla funzione lambda. Puoi determinare l'elemento visualizzato con il valore dell'indice specificato:

Carousel può essere un elemento di un elenco lazy, ad esempio LazyColumn. Il seguente snippet mostra il composable FeaturedCarousel sopra tutti i composable SectionRow: