0
0

More than 1 year has passed since last update.

HorizontalPagerにIndicatorをつける

前回、HorizontalPagerを配置しました。これに、インジケーターをつけていきます。

完成イメージはこちらです。
indicator_AdobeExpress.gif

データ構造

前回と同じですが、天気予報は、以下のデータ構造をしています。

Forecast(天気予報)
    └ List<AreaOverview>(地域データ一覧)
        ├ name(地域名)
        ├ code(地域コード)
        └ overviews(今日と明日とあれば明後日の天気予報)
            ├ weatherCode(天気コード)
            ├ weather(天気の説明)
            └ wind(風の説明)

地域データ一覧をHorizontalPagerに表示し、インジケーターには、地域名を表示しようと思います。

ForecastScreen.kt
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ForecastPager(forecast: Forecast) {
    val pagerState = rememberPagerState()
    val pageCount = forecast.areaOverviews.count()

    HorizontalPager(
        pageCount = pageCount,
        state = pagerState,
    ) { page ->
        val areaOverview = forecast.areaOverviews[page]
        LazyColumn {
            items(items = areaOverview.overviews) { forecastOverview ->
                ForecastOverviewBox(forecastOverview)
            }
        }
    }
}

ForecastOverviewBoxは、「overviews(今日と明日とあれば明後日の天気予報)」の部分の表示Composeです。
ここにインジケーターをつけます。

ForecastScreen.kt
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ForecastPager(forecast: Forecast) {
+    val coroutineScope = rememberCoroutineScope()
    val pagerState = rememberPagerState()
    val pageCount = forecast.areaOverviews.count()

+    LazyRow(
+        modifier = Modifier.fillMaxWidth(),
+        horizontalArrangement = Arrangement.Center,
+    ) {
+        items(pageCount) { page ->
+            val buttonColors = if (pagerState.currentPage == page) {
+                ButtonDefaults.filledTonalButtonColors()
+            } else {
+                ButtonDefaults.outlinedButtonColors()
+            }
+
+            Button(
+                modifier = Modifier.padding(4.dp),
+                border = BorderStroke(1.dp, MaterialTheme.colorScheme.primary),
+                colors = buttonColors,
+                shape = RoundedCornerShape(percent = 10),
+                onClick = {
+                    if (pagerState.currentPage != page) {
+                        coroutineScope.launch {
+                            pagerState.animateScrollToPage(page)
+                        }
+                    }
+                },
+            ) {
+                Text(forecast.areaOverviews[page].areaName)
+            }
+        }
+    }

    HorizontalPager(
        pageCount = pageCount,
        state = pagerState,
    ) { page ->
}

表示中ページかの判定は「if (pagerState.currentPage == page)」の部分です。
これがtrueの場合は塗りつぶしで、falseの場合は枠のみにしています。

ボタンをタップした際にページを切り替えている部分は、「pagerState.animateScrollToPage(page)」です。
scrollToPageだと、アニメーションなしで切り替わります。

参考

こちらを参考にしました。
https://github.com/android/snippets/blob/42a9747279e5dab074bdf24f60eb69c15886fe88/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L366-L398

0
0
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
0
0