どろあそび (5)
「Android Kotlin の基礎」も半分のレッスン5まで進みました。
レッスン5では「アーキテクチャコンポーネント」という大仰な名前のネタを扱います。
AndroidアプリはXMLで記述した画面レイアウトファイルと対応するアクティビティまたはフラグメントコードで構成され、アクティビティまたはフラグメントのコードが画面の生成、表示とUI操作への対応を行なっています。
フラグメントは状態遷移により、ユーザーの意図しない再初期化が発生する場合があるため、レッスン4では再開用データの保存と再利用による対応が説明されました。
レッスン5ではフラグメントのデータ管理をフラグメントコードから分離してビューモデル (ViewModel) で管理することによりフラグメントの状態遷移による意図しない再初期化の影響を抑える方法を扱います。
また、ライブデータ (LiveData) を使用したデータの更新をトリガーとした画面更新の機能導入とレッスン3で扱ったバインディング (Binding) をライブデータと組み合わせることでフラグメントコードを経由せずにビューモデルによるデータ更新を画面に直接反映させる、UI操作をビューモデルに直接反映させる方法も扱います。
最初の項目「ViewModel」ではビューモデルの作成とフラグメントコードからの利用について扱っています。
フラグメントのビュー初期化コールバック (onCreateView) でビューモデルの初期化を行うのですが、当然ながらここでビューモデルの初期化を行うと画面が回転した時などビュー初期化コールバックがよばれるたびにビューモデルが初期化されてしまうため、データを維持することができません。
このような状態を避けるため、ビューモデルではファクトリーによる初期化を導入しています。
ビュー初期化コールバックにおいてビューモデルオブジェクトを直接生成するのではなく、ビューモデルオブジェクトを生成するビューモデルプロバイダ (ViewModelProvider) にオブジェクト生成を依頼します。
なお、ビューモデルの生成において何らかの引数が必要などといった場合にはビューモデルを生成するためのファクトリークラスを用意し、ファクトリークラスのオブジェクトをビューモデルプロバイダに渡すことでビューモデルの生成を行います。
ビューモデルプロバイダは該当するビューモデルオブジェクトが生成されていなければ新規に生成し、すでに生成されていればそれを返すという動作をおこないます。
ビューモデルプロバイダのこの動作によりビューモデルオブジェクトの生成・消滅が適切に管理されることになります。
その後はフラグメントが表示に使用するデータをビューモデルで管理し、フラグメントはデータの処理をビューモデルに委託することでUI操作・表示とデータ管理を分離することができるようになります。
2番目の項目「LiveData and LiveData observers」はデータの更新によりイベントを発生するライブデータ (LiveData) とライブデータの発生したイベントを監視するライブデータオブザーバー (LiveData observer) を扱います。
ビューモデルで管理するデータを可変ライブデータ (MutableLiveData) でプライベート変数として定義し、ライブデータ (LiveData) を公開変数としてゲッターに可変ライブデータを設定して定義します。
そしてフラグメント上ではライブデータのオブザーバーを設定することで可変ライブデータの内容が更新されるとフラグメント上でライブデータの更新が通知され、表示に反映することができます。
ライブデータを使用することでボタンがタップされるなどのUI操作が発生した際、フラグメントコードは対応するビューモデルの手続きを呼び出すだけで画面の更新などは自動的に行われるようになります。
また、この項目ではライブデータの使用方法として単に画面に表示させるだけでなくイベントとして画面遷移を行わせる例が示されています。
普通に考えて画面遷移のボタンが押された時にビューモデルに値の更新を指示して、値の更新で発生するイベントで画面遷移を行うというのは無駄なような気がしますが、後の項目でこのような面倒な手間をかける理由が種明かしされます。
3番目の項目「Data binding with ViewModel and LiveData」はフラグメントコードを介在せずにフラグメントレイアウトとビューモデルを直接連携させる手順を扱っています。
まず、レイアウトのlayout要素にdata要素を追加し、レイアウト内での参照名とビューモデルの完全修飾クラス名を記述します。合わせてフラグメントコードでもバインディングにビューモデルオブジェクトを設定します。
これによりレイアウト中のView要素やButton要素などのUI要素でビューモデルが参照できるようになり、ライブデータの表示、ビューモデル手続きの呼び出しが可能になります。
なお、この項目では数値型のライブデータを文字列型に変換する方法や表示フォーマットの付加についても扱っています。
最後の項目「LiveData transformations」はライブデータを凝った表示形式で表示する方法である変形 (Transformations) を扱っています。
日付データをロケール指定に合わせた日付文字列に変換するなどは表示フォーマットのレベルで実行できるものではありません。
このため、そのままレイアウトに表示することはできず、フラグメントコード上のオブザーバーで値更新を検出したら表示形式の変換を行ってレイアウトに出力する必要が出てきます。
これに対応してフラグメントコードを経由せずに複雑な表示形式変換を行う手法が変形になります。
ライブデータとその変換手続きで初期化したTransformations.mapオブジェクトは元のライブデータと同様に振る舞い、値として変換手続きを通して得られた結果を与えるので、このような場合にもフラグメントコードを使用する必要がなくなります。
ただし、表示形式をビューモデルが意識しなければいけない点が責務の適正な配置という点でちょっと疑問ですけど。
なお、この項目ではカウントダウンタイマーの表示で変形を使用する例となっていますが、同時にカウントダウンが終了した時点で画面遷移を引き起こすようになっており、2番目の項目で導入したライブデータによる画面遷移の使い方も合わせて示しています。
次のレッスン6は永続的データストアであるRoomの扱いになります。
0コメント