Tworzenie przeglądarki katalogu

Aplikacja do multimediów, która działa na telewizorze, musi umożliwiać użytkownikom przeglądanie oferty treści, dokonywanie wyboru i rozpoczynanie odtwarzania. 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 z katalogu filmów.

Użyj funkcji dostępnych w Compose na TV, aby zaimplementować 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 wyświetlaczu, jest implementowane jako funkcja typu „composable” w Compose na TV. Zacznij od zdefiniowania funkcji typu „composable” 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.
  • funkcję wywołania zwrotnego, która aktywuje przejście między ekranami;

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 umieścić sekcje pionowo. LazyColumn udostępnia blok LazyListScope.() -> Unit, który oferuje DSL do definiowania zawartości elementu. W tym przykładzie każda sekcja jest umieszczona 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 tym przykładzie funkcja typu „composable” SectionRow określa, jak wyświetlać sekcje. W poniższej funkcji LazyRow pokazuje, jak ta pozioma wersja LazyColumn jest używana 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 tekstu zgodnie z definicją w Material Design, odwołując się do obiektu MaterialTheme. 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. Mają ten sam obszar i nie ma między nimi żadnej różnicy wizualnej. Możesz wyróżnić niektóre z nich za pomocą Carousel.

Karuzela wyświetla informacje w zestawie elementów, które mogą się przesuwać, zanikać lub pojawiać w widoku. Za pomocą tego komponentu możesz wyróżniać polecane treści, takie jak nowo dostępne filmy lub nowe odcinki programów telewizyjnych.

Carousel wymaga co najmniej określenia liczby elementów w karuzeli i sposobu rysowania każdego z nich. Pierwszy z nich można określić za pomocą itemCount. Drugi można przekazać jako lambdę. Do funkcji lambda przekazywany jest numer indeksu wyświetlanego elementu. Możesz określić wyświetlany element za pomocą podanej wartości indeksu:

Carousel może być elementem listy leniwej, np. LazyColumn. Poniższy fragment kodu pokazuje funkcję kompozycyjną FeaturedCarousel nad wszystkimi funkcjami kompozycyjnymi SectionRow: