JetpackCompose + HorizontalPager

# Pagerを使って天気予報画像を表示しよう

　JetpackComposeのPagerを使って、天気予報の画像を表示しようと思います。

## 依存関係の修正
JetpackComposeのPagerは、[バージョン 1.4.0-alpha03](https://developer.android.com/jetpack/androidx/releases/compose-foundation?hl=ja#1.4.0-alpha03)で、[accompanist](https://google.github.io/accompanist/pager/)から本家（androidx.compose.foundation:foundationライブラリ）に統合されました。
なので、まずは、依存関係を更新していきます。

ただ、残念なことに、現時点ではJetpackComposeのBOMは、androidx.compose.foundation:foundationを1.3.1までしかサポートしていないので、BOMが使えないため手動で定義していきます。
[BOM とライブラリ バージョンのマッピング](https://developer.android.com/jetpack/compose/bom/bom-mapping?hl=ja)

まずは、Compose全体のバージョン定義です。1.4.3にします。
```diff_gradle:app/build.gradle
android {
    composeOptions {
-        kotlinCompilerExtensionVersion '1.3.2'
+        kotlinCompilerExtensionVersion '1.4.3'        
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.8.0'
    implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')

-    implementation platform('androidx.compose:compose-bom:2022.10.00')
-    implementation 'androidx.compose.ui:ui'
-    implementation 'androidx.compose.ui:ui-graphics'
-    implementation 'androidx.compose.ui:ui-tooling-preview'
-    implementation 'androidx.compose.material3:material3'
+    implementation 'androidx.compose.ui:ui:1.4.3'
+    implementation 'androidx.compose.ui:ui-graphics:1.4.3'
+    implementation 'androidx.compose.ui:ui-tooling-preview:1.4.3'
+    implementation 'androidx.compose.material3:material3:1.1.1'
+    implementation 'androidx.compose.foundation:foundation:1.4.3'

}
```
ここまで修正してSyncNow & ビルドを行うと、以下の様なビルドエラーが発生します。
> java.lang.Error: Something went wrong while checking for version compatibility between the Compose Compiler and the Kotlin Compiler.

このエラーメッセージにあるリンクをたどると、Kotlinのバージョンが低すぎたのが原因とわかりますので、その部分を修正していきます。

https://developer.android.com/jetpack/androidx/releases/compose-kotlin?hl=ja

```diff_gradle:build.gradle
plugins {
    id 'com.android.application' version '8.0.2' apply false
    id 'com.android.library' version '8.0.2' apply false
-    id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
+    id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
    id 'com.google.dagger.hilt.android' version '2.44' apply false
}
```
```diff_gradle:app/build.gradle
    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility 17
+        targetCompatibility 17
    }
    kotlinOptions {
-        jvmTarget = '1.8'
+        jvmTarget = '17'
    }
```

これで、SyncNow & ビルドをすると、ばっちりSUCCESSになると思います。

## Pagerの追加

気象データは以下の様にアプリ内で保持しています。
```text
Forecast（天気予報）
    └ List<AreaOverview>(地域データ一覧)
        ├ name(地域名)
        ├ code(地域コード)
        └ overviews(今日と明日とあれば明後日の天気予報)
            ├ weatherCode(天気コード)
            ├ weather(天気の説明)
            └ wind(風の説明)
``` 
まずは地域名をPagerに表示します。
こんな感じ。
```kotlin:ForecastScreen.kt
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ForecastPager(forecast: Forecast) {
    val pageState = rememberPagerState()

    HorizontalPager(
        pageCount = forecast.areaOverviews.count(),
        state = pageState,
    ) { page ->
        val areaOverview = forecast.areaOverviews[page]
        Box(modifier = Modifier.fillMaxSize()) {
            Text(
                text = areaOverview.areaName,
            )
        }
    }
}
```
![pager_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491965/20fb68a9-b744-7493-be18-5b57d5060502.png)

スワイプすると、「南部」ー「北部」が切り替わるようになります。

次に、地域名の下に天気予報アイコンを表示します。
```kotlin
    HorizontalPager(
        pageCount = forecast.areaOverviews.count(),
        state = pageState,
    ) { page ->
        val areaOverview = forecast.areaOverviews[page]
        Box(modifier = Modifier.fillMaxSize()) {
            Column {
                Text(
                    text = areaOverview.areaName,
                )
                val weatherCodeUrl = "https://www.jma.go.jp/bosai/forecast/img/${areaOverview.overviews[page].weatherCode.image}"
                Log.d("weatherCodeUrl", weatherCodeUrl)
                AsyncImage(
                    modifier = Modifier.size(200.dp, 200.dp),
                    model = ImageRequest.Builder(LocalContext.current)
                        .data(weatherCodeUrl)
                        .decoderFactory(SvgDecoder.Factory())
                        .build(),
                    contentDescription = null,
                    contentScale = ContentScale.Fit,
                )
            }
        }
    }
```
HorizontalPagerは、何も変わらないです。
Pagerのコンテンツに、Coilを使用してSVG画像を表示しています。

<details><summary>(余談)coilでのSVG画像表示</summary>

coilは、PNG画像なら「ImageRequest.Builder」は不要ですが、SVG画像の場合は変換定義が必要になります。

```gradle:app/build.gradle
implementation 'io.coil-kt:coil-compose:2.4.0'
implementation 'io.coil-kt:coil-svg:2.4.0'
```
</details>


## いざ実行
[完成コードはこちら](https://github.com/jozuko/WeatherForecast/commit/0b34f6cb6c8e333d2bc3c2643da8ab329d6ea303)です。
![pager_2_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491965/49ceec50-33f5-a2bc-0e08-3dd1af975a69.gif)