Ian Warwick
02/01/2020, 10:03 AMContextAmbient always activity? I need to get at the activity to silently get a ViewModel behind the scenes using ViewModelProvider
fun getModel(): MyViewModel {
val context = ambient(ContextAmbient) as AppCompatActivity
return ViewModelProvider(context).get(MyViewModel::class.java)
}Klaas Kabini
02/01/2020, 10:15 AMIan Warwick
02/01/2020, 11:12 AMContext it could change to anythingManuel Wrage
02/01/2020, 11:29 AMIan Warwick
02/01/2020, 2:47 PMRouter API I don't require the user to provide anything to do with view models or the activity and wanted to sneakily grab it behind the scenes π the function I call startComposing() is a @Composable function and there I do that activity cast from ContextAmbient
Its not such a crime to require the user to provide the activity really though just prefer one less arg and + 1 more magic. Is a ActivityAmbient something we want to avoid? It could be useful in some scenarios but I understand it could also be misused π€Ian Warwick
02/01/2020, 2:49 PMAdam Powell
02/01/2020, 3:40 PMjust prefer one less arg and + 1 more magicoften you want the reverse of this for scalability, understandability, composability, probably lots of other -abilities π it helps when each component declares its dependencies explicitly and callers know what's in play and can influence things
Ian Warwick
02/01/2020, 4:26 PMval service = ambient(ServiceAmbient) is already quite magical! π even so I do agree with your point completely since its just an extra argument for an object the caller has access to anywayAdam Powell
02/01/2020, 4:35 PMIan Warwick
02/01/2020, 4:36 PMambient at risk of being removed?Adam Powell
02/01/2020, 4:45 PMambient() function has already been removed, but it was replaced with a val extension on the ambient types, .current I think? It's sticking around as a concept.Adam Powell
02/01/2020, 4:45 PMAdam Powell
02/01/2020, 4:48 PMContext - many of the same ideas apply to Compose's AmbientIan Warwick
02/01/2020, 4:49 PMAdam Powell
02/01/2020, 4:49 PMIan Warwick
02/01/2020, 4:50 PMAdam Powell
02/01/2020, 4:52 PMIan Warwick
02/01/2020, 4:52 PMAdam Powell
02/01/2020, 4:57 PMremember {} something in a val in a composable but use it several layers down the UI tree without those layers in between having to understand it or pass it as parametersAdam Powell
02/01/2020, 4:57 PMIan Warwick
02/01/2020, 4:58 PMval router = ambient(AmbientRouterContext)
val cardActions = CardActions(
editCard = { card ->
router.goto(MemsetDestination.CardDesigner(card.uuid))
})
HomeScreenContent(state, cardActions)
Using this router basically sets a model property above this composable HomeScreen causing it to show another XyzScreenAdam Powell
02/01/2020, 5:00 PMRouter? Can they accept an onEditCard: (Uuid) -> Unit event callback, so that the caller that does have a reference to the router can pass a lambda that makes the actual router.goto call?Adam Powell
02/01/2020, 5:00 PMAdam Powell
02/01/2020, 5:01 PMAdam Powell
02/01/2020, 5:01 PMIan Warwick
02/01/2020, 5:04 PMButton("Click Me", onClick = goto(MemsetDestination.HomeScreen))
and that goto function looks like this:
@Composable
fun goto(destination: Destination, context: GotoContext.() -> Unit = { go() }) = goto(destination.uri, context)
@Composable
fun goto(uri: String, context: GotoContext.() -> Unit = { go() }): () -> Unit {
val model = ambient(AmbientRouterContext)
return {
context(GotoContext(model, uri))
}
}
I am going a bit nuts with it but its fun π seriously cool stuffIan Warwick
02/01/2020, 5:05 PMAmbientRouterContext.Provider(value = model) {
state.currentUri.let {
findMapping(it).invoke(it)
}
}
they are across a few classesIan Warwick
02/01/2020, 5:05 PMButton("Click Me", onClick = goto(MemsetDestination.HomeScreen))Ian Warwick
02/01/2020, 5:12 PMfun HomeScreen(repository: MemoryCardRepository = get()) {
(get() is just some poor mans DI) and I chose that to be the point that gets changed from one screen to the next the only thing retained above this is "what was the last screen the user was on" and when that state.currentUri changes it constructs a new screen.Ian Warwick
02/01/2020, 5:15 PMAdam Powell
02/01/2020, 5:15 PMIan Warwick
02/01/2020, 5:20 PMval cardActions = CardActions(
editCard = { card ->
router.goto(MemsetDestination.CardDesigner(card.uuid))
}
HomeScreenContent(state, cardActions)
is that what you mean?Adam Powell
02/01/2020, 5:21 PMIan Warwick
02/01/2020, 5:21 PMIan Warwick
02/01/2020, 5:22 PMAdam Powell
02/01/2020, 5:22 PMIan Warwick
02/01/2020, 5:24 PMCardActions was a good idea over just individual lambda per action (only got two actions so far, edit and delete)Adam Powell
02/01/2020, 5:26 PM