I'm MVP lover but at the same time I'm open minded and I'm trying to improve my knowledge about MVVM and databinding:
I have forked here https://github.com/jpgpuyo/MVPvsMVVM
the original repo https://github.com/florina-muntenescu/MVPvsMVVM from @FMuntenescu
I have created several branches. In one of them, I want to show 2 different alert dialogs with diferent styles depending of the number of clicks performed on a button:
- even number of clicks -> show standard dialog
- odd number of clicks -> show droidcon dialog
You can find the branch here: https://github.com/jpgpuyo/MVPvsMVVM/tree/multiple_dialogs_databinding_different_style
I have created 2 observable fields in view model and I have added one binding adapter.
Activity:
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}">
ViewModel:
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);
}
}
With MVVM, not sure about how to implement it to be fully testable with java unit tests. I have created a binding adapter, but then:
I need a if/else in binding adapter to show one dialog or another.
I don't know how to inject a dialog helper into binding adapter, so I can't verify with unit tests, except with powermock.
I have added different styles for each dialog, because if I don't put styles, we can consider that title and message from dialog are retrieved from data layer, but it would be strange to consider that a android style is from data layer.
Is it ok inject a dialog helper into MVVM to solve this problem and make code testable?
Which would be the best way to manage alert dialogs with MVVM?