Tworzenie przeglądarki katalogu

Aplikacja do multimediów uruchomiona na telewizorze musi umożliwiać użytkownikom przeglądanie oferty, wybór treści i rozpoczęcie odtwarzania. Przeglądanie treści w aplikacjach tego typu powinno być proste, intuicyjne, atrakcyjne wizualnie i angażujące.

Przeglądarka katalogu multimediów składa się zwykle z kilku sekcji, a każda z nich zawiera listę multimediów. 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żywaj funkcji udostępnianych przez Compose for TV, aby zaimplementować interfejs użytkownika umożliwiający przeglądanie muzyki lub filmów z katalogu multimediów aplikacji.

Tworzenie funkcji typu „composable” dla katalogu

Wszystko, co jest widoczne na ekranie, jest implementowane jako funkcja kompozycyjna w usłudze Utwórz na telewizorze. Zacznij od zdefiniowania funkcji składania 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 mediów. Funkcja przyjmuje te argumenty:

  • Lista polecanych treści.
  • Lista sekcji.
  • Obiekt Modifier.
  • Funkcja wywołania zwrotnego, która aktywuje przejście ekranu.

Ustawianie elementów interfejsu

Edytor na potrzeby kompozycji na telewizory oferuje listy leniwie wczytywane, czyli komponent do wyświetlania dużej liczby elementów (lub listy o nieznanej długości). Aby umieścić sekcje w pionie, użyj funkcji LazyColumn. LazyColumn udostępnia blok LazyListScope.() -> Unit, który udostępnia interfejs DSL do definiowania zawartości elementu. W tym przykładzie każda sekcja jest umieszczona na liście pionowej z przedziałem 16 pikseli 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) { section ->
      Section(section, onItemSelected = onItemSelected)
    }
  }
}

W tym przykładzie funkcja kompozytowa Section 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 poziomej listy 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ż udostępniany przez bibliotekę materiałów na telewizorze. Card należy do biblioteki tv-material. MovieCard określa, jak dane każdego filmu są renderowane w katalogu zdefiniowanym w tym fragmencie kodu:

@Composable
fun MovieCard(
   movie: Movie,
   modifier: Modifier = Modifier,
   onClick: () -> Unit = {}
) {
   Card(modifier = modifier, onClick = onClick){
    AsyncImage(
       model = movie.thumbnailUrl,
       contentDescription = movie.title,
     )
   }
}

W przykładzie opisanym wcześniej wszystkie filmy są wyświetlane tak samo. Mają ten sam obszar 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 mogą się przesuwać, zanikać lub przesuwać w pole widzenia. Za pomocą tego komponentu możesz wyróżnić polecane treści, takie jak nowo dostępne filmy lub nowe odcinki programów telewizyjnych.

Carousel oczekuje, że określisz co najmniej liczbę elementów w karuzeli oraz sposób ich wyświetlania. Pierwszy można określić za pomocą parametru itemCount. Drugi może być przekazywany jako funkcja lambda. Lambda otrzymuje numer indeksu wyświetlanego elementu. Wyświetlony element możesz określić na podstawie 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 komponent FeaturedCarousel na wierzchu wszystkich komponentów 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)
    }
  }
}