LoginSignup
2
1

More than 1 year has passed since last update.

Jetpack Compose tvのCarouselを使う

Last updated at Posted at 2022-12-24

概要

Jetpack Compose tvにあるCarouselを使うことで、以下のような、自動で画面が切り替わるUIが実現できます。
Jetpack Compose tvでCarouselを使ったUI

Jetpack Compose tvについて

Jetpack Compose tvは2022/10/05にリリースされた、テレビ用のアプリを作成するためのComposeになります。
今回紹介するCarousel以外の、TvLazyRowImmersiveListなどのAPIに関しては以前投稿した記事がありますので、そちらを参照してください。

下準備

tvのドキュメントに沿って依存関係の宣言をしていきます。

build.gradle
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)
}

こんな感じになります。

Carouselをフルカスタマイズ.gif

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1