Tworzenie przeglądarki katalogu

Aplikacja multimedialna 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ć proste, intuicyjne, atrakcyjne wizualnie i angażujące.

Przeglądarka katalogu multimediów zwykle składa 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.

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

Użyj funkcji udostępnianych przez Compose for 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 z możliwością łączenia w Compose na telewizory. 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”, która implementuje 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 for TV oferuje leniwe listy, czyli komponent do wyświetlania dużej liczby elementów (lub listy o nieznanej długości). Zadzwoń LazyColumn aby umieścić sekcje pionowo. LazyColumn udostępnia blok LazyListScope.() -> Unit, który oferuje DSL do definiowania zawartości elementów. W poniższym przykładzie poszczególne sekcje są umieszczone na liście pionowej z odstępem 16 dp 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) { section ->
      Section(section, onItemSelected = onItemSelected)
    }
  }
}

W tym przykładzie funkcja kompozycyjna Section określa sposób wyświetlania sekcji. W poniższej funkcji 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 Section(
  section: Section,
  modifier: Modifier = Modifier,
  onItemSelected: (Movie) -> Unit = {},
) {
  Text(
    text = section.title,
    style = MaterialTheme.typography.headlineSmall,
  )
  LazyRow(
     modifier = modifier,
     horizontalArrangement = Arrangement.spacedBy(8.dp)
  ) {
    items(section.movieList){ movie ->
    MovieCard(
         movie = movie,
         onClick = { onItemSelected(movie) }
       )
    }
  }
}

W funkcji kompozycyjnej Section 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:

@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ą 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ć. Za pomocą tego komponentu możesz wyróżniać polecane treści, takie 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:

@Composable
function 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.placeholder
        ),
        contentScale = ContentScale.Crop,
        modifier = Modifier.fillMaxSize()
      )
      Text(text = content.title)
    }
  }
}

Carousel może być elementem listy leniwej, np. TvLazyColumn. Ten fragment kodu pokazuje funkcję FeaturedCarousel, która jest funkcją kompozycyjną najwyższego rzędu:Section

@Composable
fun CatalogBrowser(
   featuredContentList: List<Movie>,
   sectionList: List<Section>,
   modifier: Modifier = Modifier,
   onItemSelected: (Movie) -> Unit = {},
) {
  TvLazyColumn(
    modifier = modifier.fillMaxSize(),
    verticalArrangement = Arrangement.spacedBy(16.dp)
  ) {

    item {
      FeaturedCarousel(featuredContentList)
    }

    items(sectionList) { section ->
      Section(section, onItemSelected = onItemSelected)
    }
  }
}