概要
Jetpack Compose tvにあるCarouselを使うことで、以下のような、自動で画面が切り替わるUIが実現できます。
Jetpack Compose tvについて
Jetpack Compose tvは2022/10/05にリリースされた、テレビ用のアプリを作成するためのComposeになります。
今回紹介するCarousel以外の、TvLazyRow
や ImmersiveList
などのAPIに関しては以前投稿した記事がありますので、そちらを参照してください。
下準備
tvのドキュメントに沿って依存関係の宣言をしていきます。
dependencies {
implementation "androidx.tv:tv-foundation:1.0.0-alpha03"
implementation "androidx.tv:tv-material:1.0.0-alpha03"
}
Carouselを使う
Carouselの最短のコードは以下になります。
Carousel(slideCount = 10) {
// indexによって画像切り替え
val data = when (it % 2) {
0 -> R.drawable.app_icon_your_company
else -> R.drawable.movie
}
Image(painter = painterResource(id = data),
contentDescription = null,
contentScale = ContentScale.FillWidth,
modifier = Modifier.fillMaxSize())
}
全体のスライドの数のslideCount
と、indexによって表示するcontentを指定することによって先ほどのようなCarouselが実現できます。
他の要素
carouselState
CarouselState
を指定することができます。CarouselStateはinitialSlideIndex
を持つので、インデックスを切り替えたりする用途に使えます。
timeToDisplaySlideMillis
スライドが切り替わるのに必要なミリ秒数です。デフォルトは5000ミリ秒です。
指定するとスライドの切り替わる秒数を変更できます。
enterTransition, exitTransition
スライドが切り替わる際の画面効果を切り替えることができます。
carouselIndicator
スライドの位置や全体数を示すインジケーターを設定できます。Boxを用いて、柔軟なインジケータを作成することが可能です。
フルに生かしてみる
@OptIn(ExperimentalTvMaterialApi::class, ExperimentalAnimationApi::class)
@Composable
fun CarouselView(slideCount: Int, initialSlideIndex: Int) {
val carouselState = rememberCarouselState(initialSlideIndex)
Carousel(slideCount = slideCount,
carouselState = carouselState,
timeToDisplaySlideMillis = 1000,
enterTransition = scaleIn(),
exitTransition = slideOutVertically(),
carouselIndicator = {
val defaultSize = remember { 8.dp }
val inactiveColor = remember { Color.LightGray }
val activeColor = remember { Color.White }
Box {
Row(
horizontalArrangement = Arrangement.spacedBy(defaultSize),
verticalAlignment = Alignment.CenterVertically,
) {
repeat(slideCount) {
Text(when(it) {
0 -> "い"
1 -> "ろ"
2 -> "は"
3 -> "に"
4 -> "ほ"
5 -> "へ"
6 -> "と"
7 -> "ち"
8 -> "り"
9 -> "ぬ"
else -> "ぺ"
}, color =
if (it == carouselState.slideIndex) {
activeColor
} else {
inactiveColor
})
}
}
}
}) {
// indexによって画像切り替え
val data = when (it % 2) {
0 -> R.drawable.app_icon_your_company
else -> R.drawable.movie
}
Image(painter = painterResource(id = data),
contentDescription = null,
contentScale = ContentScale.FillWidth,
modifier = Modifier.fillMaxSize())
}
}
@OptIn(ExperimentalTvMaterialApi::class)
@Composable
fun rememberCarouselState(
initialSlideIndex: Int,
) = remember(initialSlideIndex) {
CarouselState(initialSlideIndex = initialSlideIndex)
}
こんな感じになります。