TV で使用するメディア アプリでは、ユーザーが提供コンテンツをブラウズして選び、再生を開始できるようにする必要があります。このタイプのアプリのコンテンツ ブラウジング エクスペリエンスは、シンプルで直感的で、楽しく、魅力的なものでなければなりません。
メディア カタログ ブラウザは通常、複数のセクションで構成され、各セクションにはメディア コンテンツのリストがあります。メディア カタログのセクションの例としては、再生リスト、注目のコンテンツ、おすすめのカテゴリなどがあります。
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
が、提供された DSL を呼び出して 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 ライブラリで提供されています。マテリアル デザインで定義されているテキストのスタイルは、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
などの遅延リストの項目にできます。次のスニペットは、すべての Section
コンポーザブルの上に FeaturedCarousel
コンポーザブルを示しています。
@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)
}
}
}