Sign in Go Pro

Android MVI Pattern

RecyclerView - Adapters

This lesson is for PRO members.

Upgrade today to get access to all the PRO lessons.

Unlock this lesson

Up next



Let's continue to hook up the recycler view of Tasks. We'll focus on our adapter in this lesson.


Love the lessons so far! I have some quesetions:
1. I see that we are subscribing to two different modelStores in the Tasks view (The activity subscribes to the edit task model store, and the fragment to the tasks model store). What would be a good way to make it so, we don't have to do this? Or alternatively, what would be a good way to implement multiple StateSubscriber interfaces in one class (so I could listen to the edit task model store and the tasks model store in the activity. Currently this is not possible because I can't implement StateSubscriber twice)
2. Would it make sense if in the adapter I extended ListAdapter, and from the fragment use the submitList method? (This way the Adapter wouldn't have to implement the StateSubscriber interface)
Thanks for your response in advance :)

Two good questions, thanks for your feedback!

1.- Let me unpack this question a bit. TasksActivity here is interested in the TaskEditorState for navigation purposes only. And you have TasksFragment, which, as a view-component, only concerns itself with the list of tasks, so it makes sense it would only be interested in TasksState

That said, depending on your use cases, and the way you organized your model, you could very well end up with a "View" component that needs to listen to more than one stream of state. In these cases, inheriting from StateSubscriber<S> doesn't work. You could decide to implement properties that extend it, class Foo { val bar: StateSubscriber<Bar> ; val baz:StateSubscriber<Baz> }, or add a interface DualStateSubscriber<S1,S2> and have your class extend that. It's worth noting the interface itself is really not adding much. It's more of a win on the convention/documentation side of things. You could decide to entirely drop that convention, once you and your team are familiar with the MVI pattern.

Also worth considering, you could take the state streams, combine them and expose them as a single stream. By following the state-machine approach exposed in TaskEditorState, you could combine multiple state machines into a single state. The danger with these two ideas is adding too much complexity to your designs, so I'd recommend sticking to the ideas in the previous paragraph.

2.- For sure, that should work nicely. You might lose a bit in "code symmetry" if you end up with a FooAdapter that only emits, and a parent Activity/Fragment that feeds changes into it. But at the end of the day, there's a lot of valid approaches. The general idea is to keep things simple for you and your team. One often-cited downside of MVI is complexity. Or, as I like to think about it, "New-pattern Learning Curve". That stuff is very subjective, so for me, my rule of thumb is to first ask myself "Is it correct?", and to then ask my teammates "Is this understandable?".

Thanks for the thorough answer :)
It turns out that there is much more "wiggle room" in this pattern, than I originally anticipated :D
I will also keep in mind, that it is very easy to add unnecessary complexity in MVI, so I will try to keep that to a minimum.

"Wiggle room" is a good way to think about it. A bit "meta", but here goes: I like to think about these things in terms of "mechanical engineering fit". When tolerances are too tight, you end up with a lot of boilerplate and ceremony to make things fit. (A problem you'll see in some of the MVI framework libraries out there.)

When tolerances are too loose, anything goes, and it'll be hard to align the team on a shared language. When tolerances are "just right", it's easy to assemble things together, and your architecture pattern will be flexible to unforeseen use cases.

I feel like there's a lot of merit in building your own approach and adjusting these tolerances to find the perfect fit for your own team or project.


Lessons in Android MVI Pattern