前書き(重要ではない部分)
いつものことながら、UIの状態入力イベントやStateの管理の煩雑性にあまたを悩ませていたところ、いつの間にかjetpack compose(Android)に更新が入っており、入力の扱い方のパターンに新しいパターンが追加されていました。
状態ベース(state-base)のテキストフィールドを推奨しますということで願ってもない変化です。
値ベース(value-base)のテキストフィールドと言葉関係の違いは今のところよくわかっていないですが、コードを見ると一目瞭然
旧バージョンでは
@Composable
fun SimpleFilledTextFieldSample() {
var text by remember { mutableStateOf("Hello") }
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") }
)
}
新バージョン(といってもすぐまた新しいのがでるのかもしれませんが)
TextField(
state = rememberTextFieldState(initialText = "Hello"),
label = { Text("Label") }
)
となっていて、旧バージョンで必要だった、onvalueChangeをViewModelまで引っ張って行ってみたいな煩雑性はどこか遠くに消えました。動作確認したところこれだけで入力状態を保持ることも確認できました。
!!!
今まであったonValueChangeのこだわりはどこへ行ったんだ!
だが、これは是が非でも入れたい!煩雑すぎてもう嫌だ!
!!!
というわけで、KMPの公式を見に行ったところどうやら2025年10月15日にアップデートが来ていました。GPTが言うならどうやら、新しいTextFieldに対応しているということで、公式ページには見当たらないものの、やってみないことには何とも言えないので頑張りました。
今まで1.8.2を使用していたのですがrememberTextFieldStateは使えたので一縷の望みをかけて。。。
(リファクタリングを考えるとこのレベルでの変更は今までvalue, onValueChangeでやっていたプロジェクト泣かせな変更ですね。旧バージョンももちろん使えますが)
本題
例によってプロジェクトフォルダの中のbuild.gradle.ktsを更新します。
公式の情報
https://www.jetbrains.com/help/kotlin-multiplatform-dev/whats-new-compose-190.html#dependencies
によれば色々アップデートされたみたいです。以下引用
## Dependencies
- **Gradle Plugin** `org.jetbrains.compose`, version 1.9.1. Based on Jetpack Compose libraries:
- Runtime 1.9.3
- UI 1.9.3
- Foundation 1.9.3
- Material 1.9.3
- Material3 1.4.0
- **Compose Material3 libraries** `org.jetbrains.compose.material3:1.9.0`. Based on Jetpack Material3 1.4.0. Thanks to the decoupled versions of Compose Multiplatform and Material3, you can choose a newer pre-release version for your project.
- **Compose Material3 Adaptive libraries** `org.jetbrains.compose.material3.adaptive:adaptive*:1.2.0-alpha05`. Based on Jetpack Material3 Adaptive 1.2.0-alpha10
- **Lifecycle libraries** `org.jetbrains.androidx.lifecycle:lifecycle-*:2.9.5`. Based on Jetpack Lifecycle 2.9.4
- **Navigation libraries** `org.jetbrains.androidx.navigation:navigation-*:2.9.1`. Based on Jetpack Navigation 2.9.4
- **Savedstate library** `org.jetbrains.androidx.savedstate:savedstate:1.3.5`. Based on Jetpack Savedstate 1.3.3
- **WindowManager Core library** `org.jetbrains.androidx.window:window-core:1.4.0`. Based on Jetpack WindowManager 1.4.0
Gradle Pluginと書かれている部分は自前でバージョン管理していますよというやつでその他は開発者がimplementationしてくださいというやつなので、バージョンの競合が起きていると使えないようです。
(オプション程度だと思うのですが、エラーになるなら追加でいいと思います)
とりあえず完成系は以下です(記事用にコメントしています)。
// composeと書かれた奴は勝手にバージョンを内部で管理しています
implementation(compose.runtime)
implementation(compose.ui)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
implementation(compose.components.uiToolingPreview)
// 以下はオプション
implementation("org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.9.5")
implementation("org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose:2.9.5")
implementation("org.jetbrains.androidx.navigation:navigation-compose:2.9.1")
implementation("org.jetbrains.androidx.savedstate:savedstate:1.3.5")
(おそらく)プロジェクトを始めて追加したときと同じ要素(*一部抜粋)
plugins {
alias(libs.plugins.composeMultiplatform) // ここのバージョンを変える
}
libsはlibs.versions.tomlファイルの中身ですので重要な部分は書き換え(*一部抜粋)
[versions]
#composeMultiplatform = "1.8.2"
composeMultiplatform = "1.9.1" # ここを公式
[plugins]
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }
この部分は上記で説明したcompose.*と連動しています。
注意点
使えなくなったコードがありました。
自分の環境では以下の点で変更がありました
- viewModels関数がなくなった
implementationのバージョン管理について、既存のバージョンとの競合がいくつもありました。
以下
// implementation(libs.androidx.lifecycle.viewmodel)
// implementation(libs.androidx.lifecycle.runtimeCompose)
// implementation(libs.navigation.compose)
libs.versions.tomlでmoduleを確認し、今回追加するものと同じ部分は置き換える必要がありそうです。
(必要であればバックアップをとってください。また、必要ではない環境もあるかもしれません)
個人的な感想(注釈)
ところで今回onValueChangeがなくなったことで、リアルタイムの入力バリデーションはどう実装するのが推奨になったんだろう。。。
composeの悩みの種はまだまだ続きそう。。。