Aplikacja do multimediów działająca na telewizorze musi umożliwiać użytkownikom przeglądanie treści, wybieranie ich i odtwarzanie. Przeglądanie treści w aplikacjach tego typu powinno być intuicyjne, atrakcyjne wizualnie i angażujące.
Przeglądarki katalogów zwykle składają się z kilku sekcji, a każda z nich zawiera listę treści multimedialnych. Przykłady sekcji w katalogu multimediów: playlisty, polecane treści, rekomendowane kategorie.
Użyj funkcji udostępnianych przez Compose na TV, aby wdrożyć interfejs użytkownika do przeglądania muzyki lub filmów z katalogu multimediów aplikacji.
Tworzenie funkcji typu „composable” dla katalogu
Wszystko, co pojawia się na ekranie, jest zaimplementowane jako funkcja typu „composable” w Compose na TV. Zacznij od zdefiniowania funkcji kompozycyjnej przeglądarki katalogu multimediów:
@Composable fun CatalogBrowser( featuredContentList: List<Movie>, sectionList: List<Section>, modifier: Modifier = Modifier, onItemSelected: (Movie) -> Unit = {}, ) { // ToDo: add implementation }
CatalogBrowser to funkcja typu „composable” implementująca przeglądarkę katalogu multimediów. Funkcja przyjmuje te argumenty:
- Lista polecanych treści.
- Lista sekcji.
- Obiekt modyfikatora.
- funkcja wywołania zwrotnego, która wywołuje przejście ekranu;
Ustawianie elementów interfejsu
Compose na TV oferuje leniwe listy, czyli komponent do wyświetlania dużej liczby elementów (lub listy o nieznanej długości). Wywołaj
LazyColumn
aby ułożyć sekcje pionowo. LazyColumn udostępnia blok LazyListScope.() -> Unit, który oferuje język DSL do definiowania zawartości elementów. W tym przykładzie poszczególne sekcje są umieszczone na liście pionowej z 16-dp odstępem między nimi:
@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) } } }
W tym przykładzie funkcja typu „composable” SectionRow określa sposób wyświetlania sekcji.
W funkcji poniżej LazyRow pokazuje, jak ta pozioma wersja funkcji LazyColumn jest używana do zdefiniowania listy poziomej z blokiem LazyListScope.() -> Unit przez wywołanie podanego DSL:
@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) } ) } } }
W funkcji kompozycyjnej SectionRow używany jest komponent Text.
Tekst i inne komponenty zdefiniowane w Material Design są dostępne w bibliotece tv-material . Możesz zmienić styl tekstów zdefiniowany w Material Design, odwołując się do obiektu MaterialTheme.
Ten obiekt jest też dostępny w bibliotece tv-material.
Card jest częścią biblioteki tv-material.
MovieCard określa sposób renderowania poszczególnych danych filmu w katalogu zdefiniowanym w tym fragmencie:
@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, ) } }
Wyróżnianie polecanych treści
W opisanym wcześniej przykładzie wszystkie filmy są wyświetlane w ten sam sposób.
Mają taką samą powierzchnię i nie różnią się wizualnie.
Niektóre z nich możesz wyróżnić za pomocą Carousel.
Karuzela wyświetla informacje w zestawie elementów, które można przesuwać, przenikać lub wsuwać. Ten komponent służy do wyróżniania polecanych treści, takich jak nowo dostępne filmy lub nowe odcinki programów telewizyjnych.
Carousel
oczekuje, że podasz co najmniej liczbę elementów w karuzeli i sposób rysowania każdego z nich. Pierwszy z nich można określić za pomocą parametru itemCount. Drugi z nich
może być przekazywany jako lambda. Do funkcji lambda przekazywany jest numer indeksu wyświetlanego elementu. Wyświetlany element możesz określić za pomocą podanej wartości indeksu:
@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 może być elementem listy leniwej, np. LazyColumn.
Poniższy fragment kodu pokazuje funkcję kompozycyjną FeaturedCarousel na wszystkich funkcjach kompozycyjnych 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) } } }