Chris Fillmore
04/06/2022, 9:44 PMrememberLauncherForActivityResult
and Compose Navigation?@Composable
fun MyNavHost() {
val launcher = rememberLauncherForActivityResult(contract = ...) { result ->
// handle 'result'
}
NavHost(...) {
composable(...) {
MyScreen(onClick = { launcher.launch(...) })
}
}
}
My assumption is that we would want a 1-1 relationship between an ActivityResultLauncher and a nav graph Destination. Right?
This trivial example is fine, but if you add more and more screens (most of which do not rely on a launcher), and more launchers (photos, permissions, whatever), it’s hard to tightly scope the related concerns. I would like to have code where the onResult
callback is adjacent to the definition of the Destination.class ActivityResultNavigator : Navigator<ActivityResultNavigator.Destination>()
But I’m not sure what to do about the ActivityResultLauncher. Using rememberLauncherForActivityResult
doesn’t really help since it has the same problem as my above sample code. That is, I can’t create the launcher adjacent to the Destination, because it relies on a Composable context.
I could define my own ActivityResultLauncher but I’m unsure how to manage its lifecycle in the context of Navigation and Compose.Alex Vanyo
04/06/2022, 10:10 PMrememberLauncherForActivityResult
inside MyScreen
? Or perhaps right next to MyScreen
inside the composable(...) {
block.
rememberLauncherForActivityResult
internally handles the lifecycle considerations automatically, so you’re free to define it locally where you need it.
(That is a notable difference from the non-Compose world with activity results, where you have to be more careful about always creating them in the same order)Ian Lake
04/06/2022, 10:21 PMcomposable(...) {
val launcher = rememberLauncherForActivityResult(contract = ...) { result ->
// handle 'result'
}
MyScreen(onClick = { launcher.launch(...) })
}
or put it inside MyScreen
Chris Fillmore
04/06/2022, 10:39 PMregisterForActivityResult
say
This must be called unconditionally, as part of initialization path, typically as a field initializer of an Activity or Fragment.This led me to conclude that I could not call this (via
rememberLauncherForActivityResult
) within a composable screen. But I didn’t test it; I just assumed.Ian Lake
04/06/2022, 10:53 PMif
block - just like any other remember
method, it would be forgotten if not part of your ouput)rememberSaveable
under the hoodChris Fillmore
04/07/2022, 2:28 PM