この記事は
こちらと共にご覧ください
実装方法よりも仕組みを掘り下げてViewModelが、一体なんなのかがわかるように解説していきます。
コードについては、殆ど触れてません。
コードラボに書き方に関しては充実していると思います。
そして、前提としてView-ViewModel間の関係をお寿司屋の「客」と「板前」に例えて解説していきます。
ViewModelとは
ViewModel は、ライフサイクルを意識した方法で UI 関連のデータを保存し管理するためのクラスです。ViewModel クラスを使用すると、画面の回転などの構成の変更後にデータを引き継ぐことができます。
このようにあります。
画面には、ライフサイクルというものがあります。
これは「人生」みたいなものですね。
つまり、画面には誕生してから、時には鬱になったり、はたまた復活したり、そして死ぬというプロセスがあるということです。
現実的には、まぁスマホを使っているとよくアプリ間を行き来することがあると思いますが、その際にアプリのシステムによって画面を停止や再開、破棄など状態が変化しているという事です。
本来それは、システムが知っていることなのですが、ライフサイクルを意識しているというのは、ライフサイクルメソッドを通じて、それらの画面の状態を知っているということになります。
話がそれました。
簡単に言うと、画面にも「人生」があって、色々ある。
ということが分かれば良いです。
ViewModelというのは、画面で使われるデータを保存して、管理する役割があります。
例えば、TextViewやBottomViewにセットする文字列やViewの表示・非表示のためのBoolean等。
さて、冒頭でView-ViewModel間の関係をお寿司屋の「客」と「板前」の関係と捉えました。
これをもう少し詳しく説明すると、「分業」を再現しているという事です。
お寿司やでは、お寿司を食べる「客」とお寿司を握る「板前」が存在しています。
この「分業」があることで、円滑にお店が回っているわけです。
逆に、「分業」がないと、「客」がセルフサービスでお寿司を握ることになってしまします。(それは、それで面白そうだが)
つまり、「客」の負担が増えてしまいます。
このことについて、ドキュメントの抜粋を見てみましょう。
アクティビティやフラグメントなどの UI コントローラの主な目的は、UI データの表示、ユーザー操作への対処、オペレーティング システムとのやり取り(権限のリクエストなど)を行うことです。UI コントローラに対してデータベースやネットワークからのデータ読み込みも行うよう要求すると、クラスが肥大化することになります。 UI コントローラに過度の役割を割り当てると、アプリの作業を他のクラスに任せずに 1 つのクラスですべて処理しようとすることになり、テストも極めて困難になります。
UIコントローラというのは、ドキュメントの文言からして、「客」(View)の事と捉えて大丈夫そうです。
ActivityやFragmentが必要以上の処理することは、クラスの肥大化を招いてしまうので、良くないよね!
と、「客」の負担が増えてしまうことを懸念していることがわかるかと思います。
ドキュメント内のViewModelを実装するの段落で、実際にコードが書かれているかと思いますが、
LiveDataが出現して解説がややこしくなるので、コードに関しては割愛します。
とりあえず、ViewModelクラスを継承すれば「板前」になれる。
そして、View側には
val model: MyViewModel by viewModels()
と記述することによって依存関係を繋ぐことで、まるで「板前」さんの「出勤」が完了されることだけ分かれば十分です。
さてさて、最初の方に少しだけ触れたViewModelの「人生」、ライフサイクルについて、掘り下げていきたいと思います。
ドキュメントでは、上記の図式とともにActivityとViewModelのライフサイクルの対応について書かれています。
これは、お寿司屋的には「客」が来店して、注文し、食事したり、会計をしたりして帰るまで、「板前」はずっと付きっきりというわけです。
アクティビティが終了して破棄されるまで存在します。
ドキュメントでは、このように表現されていますね。
ちなみに、最後のonClear()メソッドはViewModelの消滅を意味します。
板前さんの「帰宅」ですね。
と、こんな感じで良いですかね。
その後のFragment間でデータを共有することに関しては、「客」間で、お寿司のデータを共有するときは、ActivityスコープのViewModelを用いると良いよ!と言っています。
そのあとは、コルーチンの話で ViewModel単体のお話で無くなるので以上にしたいと思います。
終わり
実際に実装するとなると、もうちょい仕組みの理解が必要ですかね。
下記、記事が書き方に関してわかりやすいかなと。
ただ、ViewModelProvidersの書き方あんまり馴染みない・・・
こんな感じの記事を今後も書いていきやす。
また、ツッコミお待ちしております!
