SimpleMVI
SimpleMVI copied to clipboard
Lightweight Android MVI library for uni-directional architecture
SimpleMVI
Lightweight Android MVI library for uni-directional architecture.
The goal is to provide a set of APIs and interfaces that can conveniently setup a complex screen with many different states in a highly structured manner.
What is MVI?
MVI is a uni-directional architecture for Android.
This library takes a simplified & practical approach for configuring MVI for real-world cases.
Intent Result ViewState
MviView --------> MviProcessorHolder --------> MviReducerHolder ----------> MviView
| |
---------------------- MviViewModel ----------------------
Explained well in this video : https://www.youtube.com/watch?v=64rQ9GKphTg (Benoît Quenaudon)
Setup
Gradle
From jcenter :
implementation 'com.trent.simplemvi:simplemvi:0.9.4'
RxJava 2 is required.
How to use
Initial Setup
Let's say we want to create a screen with name Main
.
Start by creating sealed class
for each of the required components, Intent
, Result
and ViewState
.
sealed class MainIntent : MviIntent
sealed class MainResult : MviResult
sealed class MainViewState : MviViewState
Also create other classes that implement MviProcessorHolder
, MviReducerHolder
.
class MainProcessorHolder(model: MainModel) : MviProcessorHolder<MainIntent, MainResult>
class MainReducerHolder : MviReducerHolder<MainResult, MainViewState>
Create a ViewModel
& View
as well.
class MainViewModel(
processorHolder: MviProcessorHolder<MainIntent, MainResult>,
reducerHolder: MviReducerHolder<MainResult, MainViewState>
) : MviViewModel<MainIntent, MainResult, MainViewState>(processorHolder, reducerHolder)
class MainView(
containerView: View, viewModel: MainViewModel
) : MviView<MainIntent, MainResult, MainViewState>(viewModel)
In your Activity or Fragment, initialize at Activity onCreate()
with code similar to this.
viewModel = ViewModelProviders.of(
this,
MviViewModelFactory(
MainProcessorHolder(MainModel()),
MainReducerHolder()
)
).get(MainViewModel::class.java)
MainView(this.view, viewModel).apply {
lifecycle.addObserver(this)
setup()
}
You may need more methods & parameters for your classes depending on how you initialize your View references etc.
Use MviActivity
or MviFragment
for faster setup.
Configuration Workflow
Whichever way you go about configuring MVI is fine, I usually go back and forth, but generally I do this. I recommend you to find your workflow as well.
- Draw XML layouts.
- Sketch possible states of the view with
ViewState
. - Configure
render()
method ofMainView
such that view is drawn correctly according toViewState
. - Sketch possible actions that user will take to change the view with
Intent
. - Configure callbacks such as
View.setOnClickListener()
correctly such that user actions will trigger correctIntent
tointentsSubject
, passing it toMainProcessorHolder
. - Implement
Result
&MainProcessorHolder
such thatIntent
can produce correctResult
. Handle side-effects such as DB & Networking while processing intents as well. This result will be passed toMainReducerHolder
. - Implement
MainReducerHolder
such thatResult
will produce correctViewState
in combination with previousViewState
. This resulting view state will be passed toMainView
, and the new view state will be rendered.
After initial configuration, you will find that modification is a breeze.
See sampleapp
module for detailed recommended usage.