Pagerを使って天気予報画像を表示しよう
JetpackComposeのPagerを使って、天気予報の画像を表示しようと思います。
依存関係の修正
JetpackComposeのPagerは、バージョン 1.4.0-alpha03で、accompanistから本家(androidx.compose.foundation:foundationライブラリ)に統合されました。
なので、まずは、依存関係を更新していきます。
ただ、残念なことに、現時点ではJetpackComposeのBOMは、androidx.compose.foundation:foundationを1.3.1までしかサポートしていないので、BOMが使えないため手動で定義していきます。
BOM とライブラリ バージョンのマッピング
まずは、Compose全体のバージョン定義です。1.4.3にします。
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のバージョンが低すぎたのが原因とわかりますので、その部分を修正していきます。
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
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility 17
+ targetCompatibility 17
}
kotlinOptions {
- jvmTarget = '1.8'
+ jvmTarget = '17'
}
これで、SyncNow & ビルドをすると、ばっちりSUCCESSになると思います。
Pagerの追加
気象データは以下の様にアプリ内で保持しています。
Forecast(天気予報)
└ List<AreaOverview>(地域データ一覧)
├ name(地域名)
├ code(地域コード)
└ overviews(今日と明日とあれば明後日の天気予報)
├ weatherCode(天気コード)
├ weather(天気の説明)
└ wind(風の説明)
まずは地域名をPagerに表示します。
こんな感じ。
@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,
)
}
}
}
スワイプすると、「南部」ー「北部」が切り替わるようになります。
次に、地域名の下に天気予報アイコンを表示します。
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画像を表示しています。
(余談)coilでのSVG画像表示
coilは、PNG画像なら「ImageRequest.Builder」は不要ですが、SVG画像の場合は変換定義が必要になります。
implementation 'io.coil-kt:coil-compose:2.4.0'
implementation 'io.coil-kt:coil-svg:2.4.0'
いざ実行
完成コードはこちらです。