如果MVVM完全是关于数据绑定而不能做view.doThis()
之类的东西,否则它是MVP,那么如何调用视图上的动作?
假设我的视图有snackbar
。 View
由其ViewModel
控制。如果不ViewModel
,这snackbar
应该如何显示snackbar.show()
?
答案 0 :(得分:7)
在MVVM中,ViewModel捕获视图的状态。 View会观察ViewModel以进行更改并自行更新。因此,View& ViewModel通过更改值发生(与MVP中的方法调用相反)。
由于Snackbar
就像一个全局行为(如Toast),它可以在Activity / Fragment级别实现。因此,您可以创建一个MessageHelper
接口并将其作为依赖项传递给ViewModel。 Activity将实现它并显示Snackbar
。
示例:
但是,可能存在一些在活动级别无法实现的特定于视图的行为。对于这种情况,您可以使用databinding.Observable
来触发事件。例如,假设我们想要为特定视图设置动画。我们可以创建一个BindingAdapter
@BindingAdapter({"shakeTrigger"})
public static void showSnackbar(View view, Void trigger) {
// Do the animation here. You could add meaningful argument types to control the animation
}
在XML中,我们可以使用
来应用它 <TextView
bind:shakeTrigger="@{vm.shakeTrigger}"/>
然后,在viewModel中,您可以使用Data Binding apis触发抖动。使用BaseObservable
的一种方法是:
public class ConfigurationViewModel extends BaseObservable implements ViewModel {
@Bindable
public final Void shakeTrigger = null;
public void shake() {
notifyPropertyChanged(BR.shakeTrigger);
}
}
如果您使用RxJava,则可以从rx.Observable
实施触发器。您可以签出我的库以使用RxJava和Data Binding。
https://github.com/manas-chaudhari/android-mvvm
答案 1 :(得分:0)
简短的回答是,你不是,这实际上是一件好事。在MVVM中,ViewModel负责为视图准备和存储数据。因此它从模型中获取数据并准备在视图上设置但它没有设置值,设置值和更新视图状态是视图本身的责任,MVVM中的视图监视视图中的更改数据和更新本身。
例如,当列表为空时,将显示一个空列表页面。要在MVVM中执行此操作,请在ViewModel中为视图可见性定义状态,然后调用它emptyPageVisibility
,然后相应地更新此值。
public class PlaylistDetailViewModel extends ViewModel {
private MutableLiveData<Integer> emptyPageVisibility = new MutableLiveData<>();
private void someMethodInYourViewModel(){
emptyPageVisibility.setValue(View.VISIBLE);
}
}
然后在视图中,您会观察到这一点并在此数据更改时更新视图
viewModel.getEmptyPageVisibility().observe(this,
visibility -> emptyPageView.setVisibility(visibility));