Quick Overview
MVICore is a Kotlin-based framework that implements the Model-View-Intent (MVI) architectural pattern. It provides a set of abstractions and utilities to help developers build reactive, testable, and scalable Android applications.
Pros
- Reactive Approach: MVICore embraces a reactive programming model, making it easier to manage complex state and UI updates.
- Testability: The framework's design promotes testability, allowing developers to write comprehensive unit and integration tests.
- Scalability: The MVI pattern used by MVICore helps manage complexity in large-scale applications.
- Flexibility: The framework is designed to be modular and extensible, allowing developers to customize it to their specific needs.
Cons
- Learning Curve: Adopting the MVI pattern and understanding the MVICore framework may require a significant investment of time and effort for developers new to the concepts.
- Boilerplate Code: Implementing the MVI pattern can lead to more boilerplate code compared to other architectural patterns.
- Dependency Management: The framework's reliance on RxJava and other third-party libraries may introduce additional complexity in managing dependencies.
- Documentation: The project's documentation, while generally good, could be improved in certain areas to make it more accessible for new users.
Code Examples
Example 1: Defining a Simple Intent
sealed class CounterIntent : Intent {
object Increment : CounterIntent()
object Decrement : CounterIntent()
}
This code defines a sealed class CounterIntent
that represents the possible intents for a simple counter feature.
Example 2: Implementing a Reducer
class CounterReducer : Reducer<CounterState, CounterIntent> {
override fun reduce(state: CounterState, intent: CounterIntent): CounterState {
return when (intent) {
is CounterIntent.Increment -> state.copy(count = state.count + 1)
is CounterIntent.Decrement -> state.copy(count = state.count - 1)
}
}
}
The CounterReducer
class implements the Reducer
interface, which is responsible for updating the application state based on the received intents.
Example 3: Creating a View Model
class CounterViewModel(
private val reducer: CounterReducer
) : ViewModel<CounterState, CounterIntent>() {
override fun initialState(): CounterState = CounterState(count = 0)
override fun reduce(state: CounterState, intent: CounterIntent): CounterState {
return reducer.reduce(state, intent)
}
}
The CounterViewModel
class extends the ViewModel
interface provided by MVICore, which handles the state management and state-to-UI mapping.
Example 4: Binding the View to the View Model
class CounterFragment : Fragment(), View<CounterState, CounterIntent> {
private val viewModel: CounterViewModel by viewModels()
override fun render(state: CounterState) {
counterTextView.text = state.count.toString()
}
override fun intents(): Observable<CounterIntent> {
return Observable.merge(
incrementButton.clicks().map { CounterIntent.Increment },
decrementButton.clicks().map { CounterIntent.Decrement }
)
}
}
The CounterFragment
class implements the View
interface, which connects the UI to the CounterViewModel
and handles the rendering of the state and the emission of intents.
Getting Started
To get started with MVICore, follow these steps:
- Add the MVICore dependency to your project's
build.gradle
file:
dependencies {
implementation "com.badoo.reaktive:reaktive:1.2.1"
implementation "com.badoo.mvicore:mvicore:2.1.0"
}
- Create your application's state, intents, and view models following the examples provided above.
- Bind your views to the view models using the
View
interface implementation. - Observe the state changes and update the UI accordingly.
For more
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
MVICore
What's this?
MVICore is a modern, Kotlin-based MVI framework:
- Scaling with complexity: operate with a single Reducer if needed, with the option of having the full power of additional components to handle more complex cases
- Event handling: A solution to handling events that you donât want to store in the state
- Reactive component binding: A super simple API to bind your reactive endpoints to each other with automatic lifecycle handling
- Custom Middlewares: for every single component in the system, with flexible configuration options
- Logger: An out-of-the-box logger Middleware
- Time Travel Debugger: for ALL of your reactive components (not just your state machine!) with UI controls for recording and playback
Documentation
The library comes with lots of powerful capabilities and tooling.
See https://badoo.github.io/MVICore/ for full documentation.
Download
Available through jitpack.
Add the maven repo to your root build.gradle
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
Add the dependencies:
- Framework:
implementation 'com.github.badoo.mvicore:mvicore:{latest-version}'
- Binder (for versions higher than 1.2.4)
implementation 'com.github.badoo.mvicore:binder:{latest-version}'
- Helper classes for Android:
implementation 'com.github.badoo.mvicore:mvicore-android:{latest-version}'
- ModelWatcher for efficient view updates
implementation 'com.github.badoo.mvicore:mvicore-diff:{latest-version}'
- Time Travel Debugger controls in a DebugDrawer module (You need to add the dependencies to DebugDrawer and configure it yourself before you can use this):
implementation 'com.github.badoo.mvicore:mvicore-debugdrawer:{latest-version}'
Related articles & videos
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot