Hi guys, how you managed having ~15 LiveData in on...
# android-architecture
h
Hi guys, how you managed having ~15 LiveData in one view-model? Have events that could initiate 4-5 LiveData updates.
t
One possible strategy: Model the 15+
LiveData
as smaller groupings. For example: keep just one/two
LiveData
that handles high-level state in the
ViewModel
. Then, map the main
LiveData
into more specific chunks of
LiveData
. Such mapping is better suited to some other “helper” component that you can use in the
ViewModel
. This will move out a lot of detail from the
ViewModel
👍 2
a
If it is an incredibly complex screen than there could be 15 observable fields or livedata objects Just look at the duplication , if there is some remove unnecessary livedatas
j
In my current project, if there were 10 LiveData or above, I decided to create
hogehogeViewState.kt
to managed all of Livedata . Basically , the purpose of this separating is that easy to management and easy for testing .
u
Create one livedata with State that has everything
💯 1
a
The solution above (to post everything in one live data) is bug prone as LiveData propagates only latest value and if the state actively changes and those changes need to be reflected on the screen (every change step by step) you may have problems with newer value overriding the previous and having "gaps" in your flow
h
@ursus is it means that every time when i have a small change i must update all views?
u
well, technically yes, but practically only update what actually changed, so make your view calls idempotent
its a view level concern anyways
h
@ursus it is better suited for @compose which internally checks data changed and then redraws itself
u
not really, even todays views do do it, but not everywhere
view.setVisibility is idempontent, etc, youll need to look at sources, and where it lacks just do it yourself its easy
if state.subState !== previousState.subState change given view somehow
h
I am trying out this new flow in which I control every view with its own live data. It allows me to remove all the, if else conditions from the UI, As you can guess I have to create a lot of Live data's for this. I organize them using kotlin object, Transformations and with some extention function that will only post values if they are not similar to new ones.
i
My experience with your approach was not good enough.
The best approach was to actually create a proper “view-model” in the sense that it’s a immutable data class with all the attributes that models the view inside a single LiveData<MyViewModelDataClass>
For events, I create a LiveEvent that is implemented as a “decorator” around LiveData + Event<out T> and expose a single LiveEvent with an “enum” or a “sealed class” to represent events.
So, the view model always have a single liveData and liveEvent as “funnel” to the view
h
yeah this is how I usually do it. but as I said I am trying out the above approach 😅
g
same here, moved to one
uiState
LiveData (maybe another one for events) and never looked back.
h
@ghedeon how much complexity have your views?
g
exactly 3¼ shenanigans on a good day. Yours?
h
Hmm how do you deal with one LiveData? As i know one LiveData can take up to 2 shenanigans
g
the beauty of this approach is that only the
when
block grows with scale, not the complexity of LiveData. Plus, in a good architecture logic is isolated in independent units, maybe custom views in your case. As long as every unit knows how to render it's own "complex" state, the composition of all states is a trivial task
d
15 LiveData are only a problem when the logic filling them is entirely located in the view model. For example the main screen in my app is very complex (22 LiveData) but the ViewModel is still only 200 Lines big. The solution was to create different commanders (think of a class responsible for a subset of the functionality of the screen) and make the ViewModel subscribe to them. So all the view model has to do is some minor mapping of the commands from the commanders to the LiveData
Also regarding to the
ViewState
approach: This falls down when you need to have one off events (SingleLiveData) and normal LiveData. So I personally like to keep the flexibility of separate LiveData
💯 1
g
wow... hard to decide between 2 LDs (state and events) and 15 LD (basically 30 fields _liveData + liveData). But to be honest it has nothing to do with LD, it boils down to MVVM vs MVI and as long as you're consistent with the chosen approach everything probably makes since in your system of coordinates.
u
single State scales way better, as you can as you said split viewmodel into subcomponents which emit their own state, and parent viewmodel just composes it.
I used this to very much success in a chat app, where all the complex stuff lives in the bottom bar - text, @ mentions, gallery picker, gifs, edit state, also top bar has currently present users in the room etc
my State would be just State(TopState, BottomState, Messages)
worked flawlessly, only downside is you need to make your views idempotent manually, but the === identity operators works with 99% of case
I dont like multiple data because, to me its not clear the threading of when I update 2 LD synchronously, probably theyre both posted and then you can run into trouble. If its a single one, updates are always atomic
💯 1
and state is again implicit, not explicit, and not passed via ctor most likely, so testing...
h
How you deal with events?
do you have another LiveData for events?
u
yes,so actually its 2 LD, correct, but single state
h
@miqbaldc Thanks but no.