Compose
The mobiuskt-compose module provides support for
Compose Multiplatform and
Jetpack Compose with built in support
for Jetpack Navigation Component
Note: This module is experimental and likely to change in the future.
Creating a Loop
With Compose, loops are created with rememberMobiusLoop.
@Composable
fun MyScreenRoute() {
val (modelState, eventConsumer) = rememberMobiusLoop(ScreenModel()) {
Mobius.loop(MyScreenUpdate(), MyScreenHandler())
.logger(SimpleLogger("MyScreen"))
}
MyScreen(
model = modelState.value,
eventConsumer = eventConsumer,
)
}
@Composable
fun MyScreen(
model: ScreenModel,
modifier: Modifier = Modifier,
eventConsumer: (ScreenEvent) -> Unit
) {
Column(modifier = modifier) {
Text(model.labelTest)
Button(
onClick = { eventConsumer(ScreenEvent.OnClick) }
) {
Text("Button")
}
}
}
Platform Behavior
iOS/Desktop/Web
For these platforms, the loop is running while in the Composition and is disposed when removed.
The rememberMobiusLoopLocal method is available if you need to enforce this behavior on all
platforms.
Android
When using Jetpack Navigation Component, the loop will be scoped to the route and survive configuration changes.
Without Jetpack Navigation, rememberMobiusLoop uses rememberMobiusLoopLocal meaning the loop
will be disposed and recreated on configuration changes.
Supporting other Navigation libraries (Control the loop's lifecycle)
To support different navigation libraries, you must provide a custom ViewModelStoreOwner that
is tied to the libraries route lifecycle.
rememberMobiusLoop checks if LocalViewModelStoreOwner.current is set to an Activity,
in which case rememberMobiusLoopLocal is used. When it's not an Activity, we're likely
within a route for Jetpack Navigation or some other library so the loop will be held in
a ViewModel which has it's lifecyle managed by the store owner.
val navLibraryViewModelStoreOwner = ...
CompositionLocalProvider(
LocalViewModelStoreOwner provides navLibraryViewModelStoreOwner
) {
route(path = "my-screen") {
val (modelState, eventConsumer) = rememberMobiusLoop(ScreenModel()) {
Mobius.loop(MyScreenUpdate(), MyScreenHandler())
.logger(SimpleLogger("MyScreen"))
}
MyScreen(
model = modelState.value,
eventConsumer = eventConsumer,
)
}
}