Basically I have a screen, and there are a few EditText
s and a Button
.
Users have to fill in all fields otherwise the Button
is disabled.
I am using DataBinding
to achieve this. Below is my code in the viewmodel.
val isNextEnabled = MediatorLiveData<Boolean>()
isNextEnabled.apply {
addSource(field1LiveData) {
isNextEnabled.value =
it != null
&& field2LiveData.value != null
&& field3LiveData.value != null
}
addSource(field2LiveData) {
isNextEnabled.value =
it != null
&& field1LiveData.value != null
&& field3LiveData.value != null
}
addSource(field3LiveData) {
isNextEnabled.value =
it != null
&& field2LiveData.value != null
&& field1LiveData.value != null
}
}
In the xml
<Button
android:enabled="@{viewmodel.isNextEnabled}"
.
.
.
</Button>
Everything works fine as expected. But the logic above looks cumbersome. What if I have more EditText
? The code would be painful to write/maintain.
Is there any way I can simplify it?
Ultimately you have a UseCase/Logic where you decide when the
next
button is enabled.I think you should separate the logic into useCases where it makes sense.
E.g.
Now... if you need special logic and not just two-boolean algebra here, you can always extract it into use-cases that return more flows.
Or
map
it or various operations you could do:E.g.
Keep in mind this is Pseudo-code written on SO.. not even Notepad ;)
I hope that makes a bit of sense. The idea is to separate the bits into use-cases (that you can ultimately test in isolation) and to have a flow of data. When buttons change state, the fieldNFlow emits the values and this triggers the whole chain for you.
If you have the latest Coroutines (2.4.0+) you can use the new operators to avoid using LiveData, but overall, I'd try to think in that direction.
Lastly, your liveData code with a mediator is not bad, I'd at the very least, extract the "logic" into 3 different useCases so it's not all together in a series of if/else statements.
A word of caution: I haven't used Databinding in over 3(?) years, I'm personally not a fan of it so I cannot tell you if it would cause a problem with this approach.