Getting started
This page adds a first VIE screen, a counter, to an existing Compose Multiplatform project, such as one created by the Kotlin Multiplatform wizard. For an Android-only or JVM-only project, or to add the test helpers, see core:setup.adoc#jvm-or-android-only.
-
Add VIE to the common dependencies of your shared module:
build.gradle.ktskotlin { sourceSets { commonMain.dependencies { implementation("org.kodein.arch.vie:vie-mvi:0.1.0") } } } -
Declare the screen’s contract:
CounterVIE.ktinterface CounterVIE : VIE<Model, Intent, NoSignal> { (1) data class Model(val count: Int) : VIE.Model sealed interface Intent : VIE.Intent { data object Increment : Intent data object Reset : Intent } }1 ModelandIntentare imported fromCounterVIEitself, here and in the files below. This screen has nothing to signal, so it usesNoSignal, imported fromorg.kodein.arch.vie.VIE.NoSignal.The model is what the screen shows, and the intents are what the user can do.
-
Implement it with a ViewModel:
CounterVM.ktclass CounterVM : CounterVIE, VIEViewModel<Model, Intent, NoSignal>( firstModel = Model(count = 0), (1) ) { override suspend fun process(intent: Intent) { (2) when (intent) { is Intent.Increment -> update { copy(count = count + 1) } (3) is Intent.Reset -> update { copy(count = 0) } } } }1 A screen always has a model, from the very start. 2 Called for every intent the view posts, one at a time. 3 The block receives the current model and returns the next one. CounterVMis anandroidx.lifecycle.ViewModel, so it survives configuration changes on Android. -
Render it:
Counter.kt@Composable fun Counter() { VIEView(newVM = { CounterVM() }) { model -> (1) Column { Text("Count: ${model.count}") Button(onClick = { post(Intent.Increment) }) { Text("+") } (2) Button(onClick = { post(Intent.Reset) }) { Text("Reset") } } } }1 Creates the ViewModel the first time, then recomposes with every new model. 2 The view talks back by posting intents. -
Show it from your application’s root composable:
App.kt@Composable fun App() { MaterialTheme { Counter() } }
That’s it! From here, The contract explains the three types of a screen, and how to pick between an Event and an Effect for its signals.