Zoltan Demant
06/22/2022, 2:32 PMCsaba Szugyiczki
06/22/2022, 2:42 PMCasey Brooks
06/22/2022, 2:43 PMjw
06/22/2022, 2:47 PMCasey Brooks
06/22/2022, 2:53 PMcurioustechizen
06/22/2022, 2:55 PMViewModel
and that the implementation of Navigator abstraction in turn uses rememberNavController()
,
The problem is the NavController returned by rememberNavController contains activity-scoped dependencies. So it is not safe to constructor-inject into a ViewModel.
Instead, you need to use your DI library's "injection-with-parameters" feature to pass in the navController as a parameter to every ViewModel, and then use it to obtain your Navigator implementation that uses NavController.jw
06/22/2022, 2:56 PMCasey Brooks
06/22/2022, 3:00 PMZoltan Demant
06/22/2022, 3:15 PMCasey Brooks
06/22/2022, 3:18 PMSaiedmomen
06/22/2022, 3:19 PMjw
06/22/2022, 3:20 PMAdvitiay Anand
06/22/2022, 3:45 PMCasey Brooks
06/22/2022, 4:03 PMclass RouterViewModel(private val initialRoute: String) {
private val _backstack = MutableStateFlow(listOf(initialRoute))
public val backstack get() = _backstack.asStateFlow()
fun navigateTo(route: String) {
_backstack.update { it + route }
}
fun goBack() {
_backstack.update { it.dropLast(1) }
}
fun replaceTop(route: String) {
_backstack.update { it.dropLast(1) + route }
}
}
@Composable
fun App() {
val router = remember { RouterViewModel("/") }
val backstack by router.backstack.collectAsState()
val currentScreen by derivedStateOf { backstack.last() }
when(currentScreen) {
"/" -> HomeScreen()
"/settings" -> SettingsScreen()
"/account" -> AccountScreen()
}
}
The Router is just a normal class and can be passed around anywhere, so anything is free to update the backstack as it needs./posts/:postId
, and you use the route patterns in the when
block instead of specific URIs
This is the basic idea that I’ve started building with my Ballast library, though it’s nowhere near ready yet and has no documentation. But it’s all built on top of the solid and extensible Ballast MVI core library, and will benefit from things like automatic logging and time-travel debuggingAlbert Chang
06/22/2022, 4:30 PMste
06/22/2022, 4:47 PMViewModel
-free and composable-like navigation system. I also wanted the possibility to pass complex data or callbacks. This is how the code looks like:
@Composable
fun HomeScreen() {
val accountRoute: Route1<String> = rememberAccountRoute()
// it handles transition, back press etc
RouteHandler {
accountRoute { accountId: String ->
AccountScreen(
accountId = accountId,
onDidStuff = {
// I can have callbacks!
}
)
}
// main content
host {
var accountId: String by modelOrWhatever.collectAsState()
BasicText(
text = "Account",
modifier = Modifier
// go to account
.clickable { accountRoute(accountId) }
)
}
}
}
It is more verbose because of its explicitness, but I'm satisfied with the visual look of itZoltan Demant
06/22/2022, 5:33 PMeygraber
06/22/2022, 6:47 PMcurioustechizen
06/24/2022, 2:34 PMCasey Brooks
06/24/2022, 2:48 PM