2017-05-23 76 views

回答

9

像打開新的活動或示出的對話框UI相關的動作從,而不是從一個ViewModel視圖(活動或片段)觸發。 ViewModel沒有引用視圖來防止泄漏並保持表示層「被動」。

您可以訂閱您的視圖模型視圖(活動或片段),以可觀察到的,這樣,當它改變,就可以從查看啓動對話或新的活動。

+1

感謝您的回答,這個解決方案是我想象的,但我不確定這是否是最好的方法。再次感謝。 –

+1

我正在做的是創建一個LiveData 我需要在我的視圖中觸發以調用一個新的屏幕或顯示對話框的每一個動作,但我不滿意這個解決方案,這在我看來並不正確。 –

+0

我們正在爲此準備一個樣本。我將其稱爲'LiveEvent',它使用'LiveData '來檢查它是否已被調用。敬請關注。 –

-1

如果對話由用戶直接輸入觸發,說點擊一個按鈕,你可以使用事件參數來獲取一個臨時參考含活性。因此,在你的XML,如果你點擊事件綁定到一個方法:

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

您的視圖模型將有可能在它是這樣的:

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原則。我不認爲這是一個主要問題,只要您不保留對視圖參數或與其關聯的上下文的引用即可。在可測試性方面,它不會比在視圖(活動/片段)中具有可測性。就個人而言,我喜歡儘可能少地保留視圖中的代碼。

更純粹的方法可能是創建一個管理所有導航事件的導航服務。我在WPF中用MVVM Light做了類似的事情,但是Android有很大的不同,我還沒有完全探索所有我認爲有很多的陷阱。

+0

在這種情況下,VM知道UI。如果我們將改變UI邏輯(例如,將Ok和Cancel按鈕從對話框移動到邊上的Fragment),我們需要更改VM。 –

+0

@ Danylo.Vus VM知道一個視圖,不一定是任何特定的視圖。這只是一個簡短的參考。不幸的是,我很清楚沒有這樣做的好方法。 – Glaucus