Tworzenie przeglądarki katalogu

Aplikacja do multimediów działająca na telewizorze musi umożliwiać użytkownikom przeglądanie oferty 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, polecane kategorie.

Rysunek 1. Typowy ekran katalogu. Użytkownicy mogą przeglądać dane katalogu filmów.

Aby zaimplementować interfejs użytkownika do przeglądania muzyki lub filmów z katalogu multimediów aplikacji, użyj funkcji udostępnianych przez Compose na TV.

Tworzenie funkcji typu „composable” dla katalogu

Wszystko, co pojawia się na ekranie, jest implementowane jako funkcja typu „composable” w Compose na TV. Zacznij od zdefiniowania funkcji kompozycyjnej dla 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 Modifier;
  • funkcja wywołania zwrotnego, która wywołuje przejście do ekranu.

Ustawianie elementów interfejsu

Compose na TV oferuje listy leniwe, czyli komponent do wyświetlania dużej liczby elementów (lub listy o nieznanej długości). Aby umieścić sekcje pionowo, wywołaj LazyColumn. LazyColumn udostępnia LazyListScope.() -> Unit blok, który oferuje DSL do definiowania zawartości elementów. W tym przykładzie każda sekcja jest umieszczana na liście pionowej z odstępem 16 dp między sekcjami:

@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 przykładzie funkcja typu „composable” SectionRow określa sposób wyświetlania sekcji. W tej funkcji LazyRow pokazuje, jak ta pozioma wersja LazyColumn jest używana w podobny sposób do definiowania 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 MaterialTheme obiektu. Ten obiekt jest też udostępniany przez bibliotekę tv-material. Card jest częścią biblioteki tv-material. MovieCard określa, jak dane każdego filmu są renderowane w katalogu zdefiniowanym w tym fragmencie kodu:

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

W opisanym wcześniej przykładzie wszystkie filmy są wyświetlane w ten sam sposób. Zajmują tę samą powierzchnię i nie różnią się wizualnie. Niektóre z nich możesz wyróżnić za pomocą komponentu Carousel.

Karuzela wyświetla informacje w zestawie elementów, które można przesuwać, przyciemniać lub przenosić do widoku. Używasz tego komponentu do wyróżniania polecanych treści, takich jak nowo dostępne filmy lub nowe odcinki programów telewizyjnych.

Carousel wymaga podania co najmniej liczby elementów, które ma zawierać, oraz sposobu rysowania każdego elementu. Pierwszy z nich można określić za pomocą itemCount. Drugi można przekazać jako lambdę. Do lambdy przekazywany jest numer indeksu wyświetlanego elementu. Wyświetlany element możesz określić za pomocą podanej wartości indeksu:

Carousel może być elementem listy leniwej, np. TvLazyColumn. Ten fragment kodu pokazuje funkcję kompozycyjną FeaturedCarousel na wszystkich funkcjach kompozycyjnych SectionRow: