Closed11

Compose での ViewModel と状態

どっことどっこと

ちょっとだけすすめる。とりあえず、githubからcloneしてビルド完了するまでは確認できた。

どっことどっこと

ちょっと触ったけど、TextFieldに入力しても消えるのは修正させるためのバグ?

どっことどっこと

4. アプリ アーキテクチャの詳細
https://developer.android.com/codelabs/basic-android-kotlin-compose-viewmodel-and-state?hl=ja#3

モデル駆動型 UI

UseCase とか Repository から作る(=Model層)のがいいよという話。アプリのライフサイクルやコンポーネントとの関連が低いので、ここから実装すればUI側を実装する時にそれを呼び出すだけでよく嬉しい。的な。
あとは、例えばiOSエンジニアがAndroidにシフトした時に、まずはModel層から開発すれば純粋なKotlinだけを扱えてシフトがスムーズになる。(という所感)

どっことどっこと

5. ViewModel を追加する

タイトルの通り。
画面が表示する要素や、要素がタップされた時などの制御を実装しておく領域として、ViewModelを追加しそこに内包させる。
で、それにあたって、 StateFlow というクラスを使うみたい。

private には MutableStateFlow を定義しておいて、外だしするものには StateFlow として定義しておく。その時に MutableStateFlow.asStateFlow() で、参照させておく。(インスタンスとして別モノを見ることにはならないのかな。。。)

どっことどっこと

6. Compose UI を設計する

最初の onValueChange のくだりは、双方向データバインディングの話かな。

単方向データフロー は、ViewとViewModelの関係性。ViewModelがViewからのイベントを受け取って、それを処理する。処理した結果状態が変わるなら、それをViewModelが検知してそれに合わせた表示に変わる。

入力欄に何を入力してもクリアされるのは、やはり修正させるためのバグだったのか。
でも、入力欄のテキストを毎回ViewModelが受け取ると、その度にリコンポーズが走ってそうでちょっともやっとするなぁ。

どっことどっこと

7. 推測した単語を照合して、スコアを更新する

check*** という関数名は嫌だなぁ。
ドメイン知識がある人ならいいけど、そうじゃない人なら
「おおん?チェックって具体的に何するんだ?」ってなるよな。
今回はなさそうだけど、それで 真偽値を返すものならもう「それなら is**** にしろよ!」って思っちゃう。


あーなるほど。結果を真偽値で管理するけど、Uiに通知が必要だから UiStateに持たせるのか。
でも結局↑で思ったことは解消されないわ

どっことどっこと

8. スコアと単語カウントを更新する

今度はスコアを更新する処理。こちらはViewModelからの一方向だから、TextFieldの入力を受け取っていたさっきよりも単純。

どっことどっこと

9. ゲームの最終ラウンドを処理する

ゲームの終了契機の制御。ダイアログを表示してユーザに結果を通知する。
ダイアログなので、既存の画面に乗せる形で表示するので、Compose関数の最後に条件分岐を追加してダイアログのコンポーサブルを画面に追加する。

どっことどっこと

10. デバイスの回転の状態

ここではコードを修正することは特になく、 ViewModel を利用することによって 画面回転など Activity の破棄・再生成が行われた時にも、 ViewModel オブジェクトは自動的に保持され、再生成後も同様に利用できることを確認している。

画面回転だけではなく、テーマ変更(ライト/ダーク)やフォントサイズ変更を契機にも破棄・再生成は行われるから、画面回転に対応しないアプリであってもこの機能はすごく重要なんだよな。

どっことどっこと

というわけで、このCodeLabは以上。

  • ViewModelの情報を Viewに参照させるときは StateFlow を使う。特にViewModel内で値を更新する必要があるため、privateでは MutableStateFlow、外出し向けには これを asStateFlow() で StateFlow 型に変換したものを参照させる。
  • 状態を更新する時には object.copy() を使って再代入をしてあげれば、リコンポーズを促せるしデータは同じ内容だしで嬉しい。

ということが勉強になった。

このスクラップは3ヶ月前にクローズされました