KViewModel
0.2indexedLightweight library for implementing MVVM or MVI patterns, compatible with Jetpack Compose and XML. Supports exception handling, Odyssey integration, and Compose Multiplatform.
Lightweight library for implementing MVVM or MVI patterns, compatible with Jetpack Compose and XML. Supports exception handling, Odyssey integration, and Compose Multiplatform.
KViewModel it's a lightweight library for MVVM or MVI pattern. Works with Jetpack Compose, XML, UIKit.
Works with Kotlin Multiplatform and Compose Multiplatform!
Kotlin DSL
implementation("io.github.alexgladkov:kviewmodel:0.17") // Core functions
implementation("io.github.alexgladkov:kviewmodel-compose:0.17") // Compose extensions
implementation("io.github.alexgladkov:kviewmodel-odyssey:0.17") // Odyssey extensions
implementation "io.github.alexgladkov:kviewmodel:0.17" // Core functions
implementation "io.github.alexgladkov:kviewmodel-compose:0.17" // Compose extensions
implementation "io.github.alexgladkov:kviewmodel-odyssey:0.17" // Odyssey extensions
class TestViewModel : BaseSharedViewModel<TestViewState, TestAction, TestEvent>(initialState = TestViewState())
Events - for user interaction
sealed class TestEvent {
object IncrementClick : TestEvent()
object DecrementClick : TestEvent()
object DetailClick : TestEvent()
}
Actions - single action from view model like show snackbar or navigation
sealed class TestAction {
data class OpenDetail(val param: Int) : TestAction()
}
ViewState - your current screen state (fields, loaders, etc)
data class TestViewState(
val titleText: String = "",
val counter: Int = 0
)
ViewModel(factory = { TestViewModel() }) { viewModel ->
val viewState = viewModel.viewStates().observeAsState()
val viewAction = viewModel.viewActions().observeAsState()
Text(text = viewState.titleText)
viewAction.value?.let { action ->
when (action) {
is TestAction.FirstCase -> TODO()
is TestAction.SecondCase -> TODO()
}
}
}
Note: When using a custom exception handler you need to take care about crash reporting
Shared exception handlers (for all ViewModels)
class App: Application() {
override fun onCreate() {
super.onCreate()
KViewModel.setupSharedExceptionHandler(CoroutineExceptionHandler { _, throwable ->
// There is you can log common exceptions for all ViewModels
})
}
}
Single exception handlers (for only current ViewModel)
class TestViewModel: BaseSharedViewModel<TestViewState, TestAction, TestEvent>(initialState = TestViewState()) {
override fun getCoroutineExceptionHandler(): CoroutineExceptionHandler {
return CoroutineExceptionHandler { _, throwable ->
// There is you can log exceptions only for TestViewModel
}
}
}
Allows you to save the ViewModel
setupNavigation(
startScreen = "YourStartScreen",
providers = yourCustomProviders
) {
LocalRootController.current.setupWithViewModels()
generateGraph()
}
StoredViewModel(factory = { TestViewModel() }) { viewModel ->
// usual code like above
}
Feel free to make issues, we will try to fix it as fast as we can! For proposals, you can also use issue section
// ViewState
testViewModel.viewStates().watch { [weak self] viewState in
guard let self = self else { return }
self.titleView.text = viewState.someText
}
// Action
testViewModel.viewActions().watch { [weak self] viewAction in
guard let self = self, let viewAction = viewAction else { return }
switch viewAction {
case let args as TestAction.OpenDetail:
self.presentDetail(param: args.param)
default: break
}
}
Surfaced from shared tags and platforms — no rankings paid for.