2017-05-23 32 views
6

新しいアーキテクチャコンポーネントを使用してMVVMについて質問しました。私のアプリケーションで、VM内で発生したいくつかのアクションの3つのオプションを含むDialogなどを表示する必要がある場合、ダイアログを表示するコマンドをActivity/Fragmentに送信するのは誰ですか?AndroidのMVVMアーキテクチャのViewModelからダイアログを表示

答えて

9

新しいアクティビティを開く、またはダイアログを表示するなどのUI関連のアクションは、ViewModelからではなく、ビュー(アクティビティまたはフラグメント)からトリガされます。 ViewModelには、リークを防止し、プレゼンテーション層を「リアクティブ」に保つためのビューへの参照がありません。

ビュー(アクティビティまたはフラグメント)をViewModelのオブザーバブルにサブスクライブして、変更時にビューからダイアログまたは新しいアクティビティを開始することができます。

+1

あなたの答えをありがとう、このソリューションは私が想像したものでしたが、それが最良の方法であるかどうかはわかりませんでした。再度、感謝します。 –

+1

私がやっていることは、新しい画面または表示ダイアログを呼び出すために私のビューでトリガーされる必要があるすべてのアクションに対してLiveData を作成することですが、その解決策に満足していません。 –

+0

私たちは正確にこれを行うためのサンプルを作成しています。私はそれを 'LiveEvent'と呼び、' LiveData 'を使って、すでに呼び出されているかどうかを確認します。乞うご期待。 –

-1

ダイアログがユーザーの入力によって直接トリガーされる場合、たとえばボタンをクリックすると、イベントパラメータを使用して、含まれているアクティビティの一時参照を取得できます。あなたはメソッドにクリックイベントを結合しているのであれば、あなたのxmlに:

<ImageView 
    android:layout_width="24dp" 
    android:layout_height="24dp" 
    android:onClick="@{model.onClicked}" /> 

あなたのviewmodelは、おそらくその中にこのようなものがあります:

public void onClicked(View view) 
{ 
    MyDialogFragment.newInstance(
     (di, whichButton) -> doOkClicked(di, whichButton), 
     (di, whichButton) -> doCancelClicked(di, whichButton) 
    ).show(((Activity)view.getContext()).getFragmentManager(), "MyTag"); 
} 

public void doOkClicked(DialogInterface dialog, int whichButton) 
{ 
    ... 
} 

public void doCancelClicked(DialogInterface dialog, int whichButton) 
{ 
    ... 
} 

を一部の人々は、これはMVVMの原則に違反していると思われるかもしれ。ビューパラメータやそれに関連付けられているコンテキストへの参照を保持していない限り、ここでは大きな問題ではありません。テスト容易性の面では、それをビュー(アクティビティ/フラグメント)内に置くよりもテストすることは少なくありません。個人的には、できるだけビュー内にコードを少なくするのが好きです。

より純粋なアプローチは、すべてのナビゲーションイベントを管理するナビゲーションサービスを作成することです。私はWPVMでMVVM Lightを使ってこのようなことをやったことがありますが、Androidは大きく異なっていますし、十分にあると確信しているすべての問題を完全に調査していません。

+0

この場合、VMはUIについて知っています。そして、UIロジックを変更する場合(たとえば、OKボタンとCancelボタンをダイアログから別のフラグメントに移動する)、VMを変更する必要があります。 –

+0

@ Danylo.Vus VMはビューを知っていますが、必ずしも特定のビューであるとは限りません。それは簡単なリファレンスです。残念ながら、私が知っているこれを行うには本当に良い方法はありません。 – Glaucus

関連する問題