In einer Media-App, die auf einem Fernseher ausgeführt wird, müssen Nutzer die Inhalte durchsuchen, eine Auswahl treffen und die Wiedergabe starten können. Das Durchsuchen von Inhalten in Apps dieses Typs sollte intuitiv, visuell ansprechend und interessant sein.
Katalogbrowser bestehen in der Regel aus mehreren Abschnitten, die jeweils eine Liste mit Media-Inhalten enthalten. Beispiele für Abschnitte in einem Medienkatalog sind Playlists, empfohlene Inhalte und empfohlene Kategorien.
Mit den von Compose for TV bereitgestellten Funktionen können Sie eine Benutzeroberfläche zum Durchsuchen von Musik oder Videos aus dem Medienkatalog Ihrer App implementieren.
Zusammensetzbare Funktion für den Katalog erstellen
Alles, was auf einem Display angezeigt wird, wird in Compose for TV als zusammensetzbare Funktion implementiert. Definieren Sie zuerst eine zusammensetzbare Funktion für den Media-Katalogbrowser:
@Composable fun CatalogBrowser( featuredContentList: List<Movie>, sectionList: List<Section>, modifier: Modifier = Modifier, onItemSelected: (Movie) -> Unit = {}, ) { // ToDo: add implementation }
CatalogBrowser ist die zusammensetzbare Funktion, die Ihren Media-Katalogbrowser implementiert. Die Funktion verwendet die folgenden Argumente:
- Liste der empfohlenen Inhalte.
- Liste der Abschnitte.
- Ein Modifier-Objekt.
- Eine Callback-Funktion, die einen Bildschirmübergang auslöst.
UI-Elemente festlegen
Compose for TV bietet Lazy Lists, eine Komponente zum Anzeigen einer großen Anzahl von Elementen (oder einer Liste unbekannter Länge). Rufen Sie LazyColumn auf, um Abschnitte vertikal zu platzieren. LazyColumn bietet einen LazyListScope.() -> Unit-Block, der eine DSL zum Definieren von Artikelinhalten bietet. Im folgenden Beispiel wird jeder Abschnitt in einer vertikalen Liste mit einem Abstand von 16 dp zwischen den Abschnitten platziert:
@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) } } }
Im Beispiel wird mit der zusammensetzbaren Funktion SectionRow definiert, wie Abschnitte dargestellt werden.
In der folgenden Funktion wird mit LazyRow gezeigt, wie diese horizontale Version von LazyColumn ähnlich verwendet wird, um eine horizontale Liste mit einem LazyListScope.() -> Unit-Block zu definieren, indem die bereitgestellte DSL aufgerufen wird:
@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) } ) } } }
Im zusammensetzbaren SectionRow wird die Komponente Text verwendet.
Text und andere in Material Design definierte Komponenten sind in der tv-material-Bibliothek verfügbar . Sie können den Stil der Texte ändern, wie in Material Design definiert, indem Sie auf das Objekt MaterialTheme verweisen.
Dieses Objekt wird auch von der tv-material-Bibliothek bereitgestellt.
Card ist Teil der Bibliothek für TV-Material.
MovieCard definiert, wie die einzelnen Filmdaten im Katalog gerendert werden, der im folgenden Snippet definiert ist:
@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, ) } }
Empfohlene Inhalte hervorheben
Im oben beschriebenen Beispiel werden alle Filme gleich angezeigt.
Sie haben dieselbe Fläche und es gibt keinen visuellen Unterschied zwischen ihnen.
Mit Carousel können Sie einige davon hervorheben.
Im Karussell werden die Informationen in einer Reihe von Elementen angezeigt, die eingeblendet, ausgeblendet oder in die Ansicht verschoben werden können. Mit der Komponente können Sie Empfohlene Inhalte wie neu verfügbare Filme oder neue Folgen von TV-Sendungen hervorheben.
Carousel
erfordert, dass Sie mindestens die Anzahl der Elemente im Karussell und die Art und Weise angeben, wie die einzelnen Elemente gezeichnet werden sollen. Die erste kann mit itemCount angegeben werden. Die zweite kann als Lambda übergeben werden. Die Indexnummer des angezeigten Elements wird an die Lambda-Funktion übergeben. Sie können das angezeigte Element mit dem angegebenen Indexwert bestimmen:
@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 kann ein Element einer Lazy-Liste sein, z. B. LazyColumn.
Das folgende Snippet zeigt die FeaturedCarousel-Composable-Funktion über allen SectionRow-Composable-Funktionen:
@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) } } }