Criar um navegador de catálogo

Um app de mídia executado em uma TV precisa permitir que os usuários naveguem pelo conteúdo ofertas, fazer uma seleção e começar a reproduzir o conteúdo. A navegação de conteúdo para apps desse tipo deve ser simples, intuitiva e visualmente agradável e envolvente.

Um navegador de catálogo de mídia tende a ter várias seções, e cada seção tem uma lista de conteúdo de mídia. Exemplos de seções em um catálogo de mídia incluem: listas de reprodução, conteúdo em destaque, categorias recomendadas.

Figura 1. Tela típica de catálogo. Os usuários podem navegar pelos dados do catálogo de vídeos.

Usar as funções fornecidas pelo Compose para TV com o objetivo de implementar um usuário interface para procurar músicas ou vídeos no catálogo de mídia do seu app.

Criar uma função combinável para o catálogo

Tudo que aparece em uma tela é implementado como uma função combinável Compose para TV. Comece definindo um elemento combinável para o navegador de catálogo de mídia:

@Composable
fun CatalogBrowser(
   featuredContentList: List<Movie>,
   sectionList: List<Section>,
   modifier: Modifier = Modifier,
   onItemSelected: (Movie) -> Unit = {},
) {
// ToDo: add implementation
}

CatalogBrowser é a função combinável que implementa seu catálogo de mídia. navegador. A função usa os seguintes argumentos:

  • Lista de conteúdo em destaque.
  • Lista de seções.
  • Um objeto modificador.
  • Uma função de callback, que aciona uma transição de tela.

Definir elementos da IU

O Compose para TV oferece listas lentas, um componente para mostrar uma imagem grande número de itens (ou uma lista de tamanho desconhecido). Ligação LazyColumn para colocar seções verticalmente. LazyColumn oferece um LazyListScope.() -> Unit que oferece uma DSL para definir o conteúdo do item. No exemplo a seguir, cada seção é colocada em uma lista vertical com um intervalo de 16 dp entre as seções:

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

No exemplo, a função combinável Section define como mostrar seções. Na função a seguir, LazyRow demonstra como isso horizontal do LazyColumn é usado de forma semelhante para defina uma lista horizontal com um bloco LazyListScope.() -> Unit chamando a DSL fornecida:

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

No elemento combinável Section, o componente Text é usado. Texto e outros componentes definidos no Material Design são oferecidos na biblioteca tv-material . Você pode mudar os textos estilo definido no Material Design, consultando o Objeto MaterialTheme. Esse objeto também é fornecido pela biblioteca tv-material. Card faz parte da biblioteca tv-material. O MovieCard define como os dados de cada filme são renderizados no catálogo definido. no seguinte snippet:

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

No exemplo descrito anteriormente, todos os filmes são exibidos igualmente. Eles têm a mesma área, sem diferença visual entre eles. É possível destacar alguns deles com Carousel.

O carrossel exibe as informações em um conjunto de itens que podem deslizar, esmaecer ou entrar em exibição. Você usa o componente para destacar conteúdo em destaque, como filmes recém-disponibilizados ou novos episódios de programas de TV.

Carousel espera que você especifique pelo menos o número de itens que o Carrossel tem e como desenhar cada item. O primeiro pode ser especificado com itemCount. O segundo item pode ser transmitida como uma lambda. O número de índice do item exibido é dadas ao lambda. Você pode determinar o item exibido com o valor de índice fornecido:

@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 pode ser um item de uma lista lenta, como TvLazyColumn. O snippet abaixo mostra o elemento combinável FeaturedCarousel na parte de cima do Todos os elementos combináveis 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)
    }
  }
}