フラグメントにSharedViewModelを使用しないのはなぜですか?

こんにちは、こんにちは!

フラグメント間の相互作用を整理するタスクは非常に一般的です。一見すると、ShareViewModelはこれに最適です。フラグメントが表示されているowner =私たちのアクティビティでViewModelを作成し、このViewModelを各フラグメント内に取得します。なぜならViewModelの所有者はアクティビティであり、フラグメントはViewModelの同じインスタンスを取得します。これにより、データの交換、メソッドの呼び出しなどが可能になります。ドキュメントからのリンクです。

次の図は、3つのフラグメントの相互作用スキームを示しています。

画像

それら。私たちが行うこと:各フラグメントで、相互作用する必要のあるフラグメントのSharedViewModelを取得します...

そして、これは私の意見では最良の解決策ではありません。なぜなら:

  1. *VM. ViewModel View. ViewModel LiveData, View, .. ViewModel - , View.
  2. SharedViewModel — . , SharedViewModel , , . - .
  3. SharedViewModel, . , , .

SharedViewModelは、同じデータを持つ完全に同一のフラグメントが複数ある場合にのみ使用できます。私の実践では、そのようなシナリオはありませんでした。 2つの同一のフラグメントが存在する可能性がありますが、それぞれのViewModelの状態は異なり、SharedViewModelはそれらに対して無効です。

SharedViewModelには多くの問題があります。あなたは混乱し始め、すべてが依存関係に覆われ、コードは複雑です。 Fragment + ViewModelがブラックボックスの場合、作業がはるかに簡単になります。

どのようなソリューションを提供できますか?

各フラグメントが独自の方法で相互作用する単純なサービス。

画像

このサービスは、各ViewModel内で渡す必要があります。 DIとスコープ(Dagger、Koinなど)のおかげで、これは簡単かつ簡単に実行できます。サービスがアクティビティのコンテキスト内に存在する必要がある場合は、このアクティビティのスコープ内でサービスを作成し、各ViewModelに渡します。

何が起こったのかを見てください。フラグメントからすべてのSharedViewModelを削除しました。各フラグメントは、他のフラグメントについて何も知りません。このスキームに新しいフラグメントを追加する場合は、viewModel Dをサービスに接続するだけで十分です。フラグメントがサービスの一部のプロパティの変更に応答する必要がある場合-それにサブスクライブするだけです。他の人のViewModelを理解する必要はもうありません。そして、このサービスはどのViewModelよりもはるかに単純で、サービスを理解しやすくなります。

1つの画面に相互作用するフラグメントがそれほど多くないように見える場合があります。電話で-多分。タブレットで-あなたはもうそれを言うことはできません。また、FragmentContainerViewは、あらゆるレイアウトでフラグメントを使用するのに役立ちます。これは、ライフサイクルを持つ多くの共通コンポーネントがアプリケーションにある場合に非常に便利です。

おまけ:フラグメントを作成するにはどうすればよいですか?


このように:SomeFragment()

そして、パラメーターについてはどうですか?

ViewModelの登場により、パラメーターを使用しなくなりました。バンドルを介してフラグメントに何も渡さない(Android Studioでは、引数を使用してフラグメントを作成し、静的メソッドを介してフラグメントを作成することを引き続き提供しています)、ナビゲーションコンポーネントにSafety NavArgsを使用しません

これらすべてにより、フラグメントは条件付けられます。たとえば、このようなフラグメントを取得してViewPagerに追加することはできません。パラメータを渡す方法を考える必要があります。または別の例:パラメーターを使用してフラグメントを作成し、その中で作業し、データが変更され、フラグメントはすでに何か他のものを示しています。デバイス構成を変更しました(引き渡されました)。フラグメントは古いパラメーターで新しく作成されましたが、ViewModelにはすでに他のデータが含まれています。そして、パラメータ等の具体化が始まります。

ViewModelでこれをすべて削除しました。パラメータを渡すのと同じサービスを使用しています。 Safety NavArgsのように機能します。 ViewModelは、パラメータークラスのタイプによってサービスからパラメーターを要求します。パラメータが正常に取得された後、サービスはそれらを削除します(Push / Popのように機能します)。

これにより、構成を変更する問題がすぐに解決されます。フラグメントが再度作成され、ViewModelにはすでに現在のデータが含まれています。必要なのは、Viewに接続することだけです。

バンドルを介してパラメーターを渡す場合にも問題があります-これは許容量を超えています。転送されるデータの量が500 kbを超える場合、Binder.java内の例外が原因でアプリケーションがクラッシュする可能性があります。これにより、SDを介してパラメーターを送信するさまざまなライブラリーが作成されました。これは、RAMを使用する場合に比べて高速ではありません。

一般的に、ツールはクールで、すべてが柔軟ですが、注意する必要があります。

ご覧いただきありがとうございます。

All Articles