web-dev-qa-db-ja.com

代わりにアクティビティのViewModelにアクセスするフラグメントのViewModel?

問題は非常に簡単です。問題は、ViewModels、LiveData、およびその他の関連する Lifecycle 対応のArchアプローチの使用に関連しています。
NavDrawerを使用して、内部でフラグメントを切り替えるアクティビティがあります。
また、画面に2つのフラグメントが同時に存在する場合もあります。これが主な問題です。 1つのフラグメントに、ネストされたFragmentsdo n't ask why)を含むViewPagerがあります。他のフラグメントは、ユーザーがいくつかのアクションを実行したときに最初のフラグメントから情報を取得するだけです。これは、アクティビティビューモデルを共有するだけで実現できます。しかし、アプリ自体には多くのビジネスロジックがあり、さらに進むと、ビューモデルはますます大きくなります。
私が聞きたいこと-領収書やこれを修正する方法、またはプロジェクトの構造全体を修正することによってこれを克服する方法についてのルールではありません。私は、Android.Arch.lifecycleスタイル内のMVVMアプローチをマイニングのユースケースにどのように適用できるかについて提案をお願いしたいと思います。
フラグメント間でアクティビティビューモデルを共有するだけで、もっと複雑なものを見たことはありません。しかし、一般的に、それは治療法ではありません。 enter image description here

あなたがここで見ることができるもの-実際に混乱。ポイントは、すべてがActivityViewModelを共有しているということです。 FirstFragmentからのConnections(aggregation)は、ViewPager内のFirstFragmentChildFragmentsを開始しており、同じActivityViewModel(kill me)を使用していることを意味します。その結果、全員が1つの共有ViewModelで作業しています。
私の提案は、レイヤーごとにViewModelを追加することです。したがって、Activity/Fragments/ChildFragmentsには独自のViewModelがあります。しかし、ここに何が表示されますか-次にどのように通信する必要があるか
可能な解決策 :

  • 1つのコンポーネントに2つのViewModelがあります。 1つのViewModelがビジネスロジックを処理/委任し、別のViewModelが通信を行います。 コンポーネントごとに2つのビューモデル-それほど良くありませんね
  • 古い方法のインターフェースを持っている(しないでください!
  • その他の回避策-DB/SharedPrefs/Realm変更リスナーやイベントバスなど(私はこれには古すぎます:()。

  • ここにあなたの解決策!

上記のすべてが多くの設計原則を破っているので、どうすればよいですか?どうすればこの混乱から抜け出すことができますか? Uncle Bobまたは別のsuperheroが役立ちますか?

P.S。-まあ、UMLや他のグラフを作成することは私の得意ではありません。そのために残念。
P.P.S。-私は googlesamples を知っています。

16
Yurii Tsap

まず、multipleViewModelsingleビュー

ViewModelは、dataがどのように取得および操作しているかを考え、それらをグループ化します。それは自然に思えます。

あなたの場合、フラグメントとアクティビティのロジックが非常に似ている場合は、単一のViewModelで十分だと思いますが、それは避けます。

私がやろうとしていることは、アクティビティのViewModelを小さな部分に分割し、ViewModelの適切なFragmentsを再利用して、God ViewModel、または大体同じコードを別のViewModelで使用することもできません。

4
Nagy Robi

私が提案することあなたができることは、ユースケース全体に対して2つのViewModelを処理することです。

1つ作るViewModel

MyActivityViewModelactivityレベルに関連するすべてのロジックを処理するとします。したがって、もしfragmentロジックがあなたのactivityに直接関連しているなら、以下のようにViewModelを共有してください:

ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class); // Like this in fragment.

ViewModelProviders.of(this).get(MyActivityViewModel.class); // Like this in activity.

これはactivityfragmentの間で共通のViewModelを共有します。


ViewModel間でロジックを共有する必要がある場合、別のFirstFragmentがあなたのケースでChildFragmentになります。

ここでViewModelを共有できますFragmentViewModelと言いましょう:

ViewModelProviders.of(this).get(FragmentViewModel.class); // Like this in FirstFragment which is having view pager.

ViewModelProviders.of(getParentFragment()).get(FragmentViewModel.class); // Like this in View pager fragments, getParentFragment() is First fragment in our case.

ただし、FirstFragmentの子フラグメントでは、次のようにアクティビティレベルMyActivityViewModelを引き続き使用できます。

ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class);
2
Jeel Vankhede