カタログ ブラウザを作成する

テレビで動作するメディアアプリでは、ユーザーがコンテンツをブラウジングできる必要があります。 選択し、コンテンツの再生を開始します。コンテンツの閲覧 この種のアプリのエクスペリエンスは、シンプル、直感的、視覚的でなければならない 魅力的で楽しいものです。

メディア カタログ ブラウザは複数のセクションで構成される傾向があり、各セクションは メディア コンテンツの一覧があります。メディア カタログのセクションには次のようなものがあります。 再生リスト、注目コンテンツ、おすすめのカテゴリなどが表示されます。

図 1. 一般的なカタログ画面。ユーザーは動画カタログのデータを閲覧できます。

Compose for TV が提供する機能を使用してユーザーを実装する アプリのメディア カタログから音楽や動画をブラウジングするためのインターフェースです。

カタログ用のコンポーズ可能な関数を作成する

ディスプレイに表示されるものはすべて、 Compose for TV。まずコンポーザブルを定義します。 使用すると、以下のようになります。

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

CatalogBrowser は、メディア カタログを実装するコンポーズ可能な関数です。 アクセスできます。この関数は次の引数を取ります。

  • 注目のコンテンツのリスト。
  • セクションのリスト。
  • Modifier オブジェクト。
  • 画面の遷移をトリガーするコールバック関数。

UI 要素を設定する

Compose for TV には遅延リストが用意されています。遅延リストは、 アイテム数(または長さ不明のリスト)を返します。発信 LazyColumn セクションを縦に配置できます。LazyColumn は、 LazyListScope.() -> Unit ブロックは、アイテム コンテンツを定義する DSL を提供します。以下の例では、 各セクションは、セクション間に 16 dp のギャップを空けて垂直リストに配置されます。

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

この例では、コンポーズ可能な関数 Section がセクションの表示方法を定義します。 次の関数では、LazyRow を使用して、 LazyColumn の横向きバージョンも同様に使用されます。 次を呼び出して、LazyListScope.() -> Unit ブロックで水平リストを定義します。 次のように指定します。

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

Section コンポーザブルでは、Text コンポーネントが使用されます。 テキストとその他のコンポーネント マテリアル デザインで定義されているものは、tv-material ライブラリで提供されています。Google Chat では テキストを変更してマテリアル デザインで定義されているとおりに、 MaterialTheme オブジェクト。 このオブジェクトは tv-material ライブラリによっても提供されています。 Card は tv-material ライブラリの一部です。 MovieCard は、定義されたカタログで各映画データをレンダリングする方法を定義します。 次のスニペットのようになります。

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

前述の例では、すべての映画が均等に表示されます。 同じ領域で、視覚的な違いはありません。 そのいくつかは、Carousel を使用して強調できます。

カルーセルでは、アイテムをスライド、フェード、または ビューに入りますコンポーネントを使用して、次のような注目のコンテンツをハイライト表示します。 テレビ番組の新エピソードなどです。

Carousel 少なくとも、カルーセルに保持するアイテム数と、 各アイテムを描画します。最初のものは itemCount で指定できます。2 件目 ラムダとして渡すことができます。表示されているアイテムのインデックス番号は 渡されます。表示されるアイテムは、 指定されたインデックス値:

@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 は、TvLazyColumn などの遅延リストの項目にできます。 次のスニペットは、FeaturedCarousel コンポーザブルを すべての 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)
    }
  }
}