我是MVP爱好者,但同时我思想开放,我正在努力提高我对MVVM和数据绑定的知识:
我在这里分叉了https://github.com/jpgpuyo/MVPvsMVVM
来自@FMuntenescu的原始repo https://github.com/florina-muntenescu/MVPvsMVVM
我创建了几个分支。在其中一个中,我想展示2个不同的警报对话框,它们具有不同的样式,取决于在按钮上执行的点击次数:
- 偶数次点击->显示标准对话框
- 奇数次点击->显示droidcon对话框
你可以在这里找到分支:https://github.com/jpgpuyo/MVPvsMVVM/tree/multiple_dialogs_databinding_different_style
我在视图模型中创建了2个可观察字段,并添加了一个绑定适配器。
活动:
private void setupViews() {
buttonGreeting = findViewById(R.id.buttonGreeting);
buttonGreeting.setOnClickListener(v -> mViewModel.onGreetingClicked());
}
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
app:greetingType="@{viewModel.greetingType}"
app:greetingMessage="@{viewModel.greetingMessage}">
视图模型:
public ObservableField<String> greetingMessage = new ObservableField<>();
public ObservableField<GreetingType> greetingType = new ObservableField<>();
public void onGreetingClicked() {
numberOfClicks++;
if (numberOfClicks % 2 == 0) {
mSubscription.add(mDataModel.getStandardGreeting()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(greeting -> {
greetingMessage.set(greeting);
greetingType.set(GreetingType.STANDARD);
}));
} else {
mSubscription.add(mDataModel.getDroidconGreeting()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(greeting -> {
greetingMessage.set(greeting);
greetingType.set(GreetingType.DROIDCON);
}));
}
}
MVVMBindingAdapter:
@BindingAdapter({"greetingType", "greetingMessage"})
public static void showAlertDialog(View view, GreetingType greetingType,
String greetingMessage) {
if (GreetingType.STANDARD.equals(greetingType)){
new DialogHelper().showStandardGreetingDialog(view.getContext(),
greetingMessage, greetingMessage);
} else if(GreetingType.DROIDCON.equals(greetingType)) {
new DialogHelper().showDroidconGreetingDialog(view.getContext(),
greetingMessage, greetingMessage);
}
}
对于MVVM,不确定如何实现它,使其完全可通过Java单元测试进行测试。我创建了一个绑定适配器,但是:
- 我需要在绑定适配器中使用if/else来显示一个或另一个对话框。
- 我不知道如何将对话框助手注入到绑定适配器中,所以我不能用单元测试来验证,除了用powermock。
我为每个对话框添加了不同的样式,因为如果我不添加样式,我们可以认为对话框的标题和消息是从数据层检索的,但如果认为android样式是从数据层检索的,那就太奇怪了。
是否可以在MVVM中注入一个对话框帮助器来解决这个问题并使代码可测试?
使用MVVM管理警报对话框的最佳方式是什么?
1条答案
按热度按时间thtygnil1#
我用于MVVM的解决方案是混合的,如下所示。
从Jose Alcérreca的文章中提到的中等职位LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)在SO回答Show Dialog from ViewModel in Android MVVM Architecture,我选择第四个选项“推荐:使用事件 Package 程序“”。原因是,如果需要,我可以偷看消息。另外,我在Jose的Gist中添加了
observeEvent()
扩展方法。我的最终代码是:
用法如下(我的示例在数据同步完成时触发事件):
然后使用
observeEvent()
来使用它,以获得漂亮、简洁的代码: