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,
)
}
}