https://kotlinlang.org logo
#compose-android
Title
# compose-android
g

Gautam Lad

03/17/2024, 3:13 PM
Hi all, I am curious to know if it's possible for the composable containing the
NavHost
to get access to the
navArguments
that were provided to activity that is showing the composable...see 🧵 with code snippet of what I am trying to do.
Copy code
// ComposeActivity.kt
 class ComposeActivity : ComponentActivity() {
     private val imageUrl by lazy {
         checkNotNull(getNavArguments()).getString("image_url")
     }
     
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContent {
             NavigationHost(imageUrl = imageUrl)
         }
     }
 }

 // NavigationHost.kt
 @Composable
 fun NavigationHost(imageUrl: String) {
     val navController = rememberNavController()
     CompositionLocalProvider(LocalNavController provides navController) {
         NavHost(navController, startDestination = "showImage/{imageUrl}") {
             composable(
                 route = "showImage/{imageUrl}",
                 arguments = listOf(navArgument("imageUrl") {
                     type = NavType.StringType
                     defaultValue = imageUrl
                 })
             ) {
                 ShowImageScreen()
             }
         }
     }
 }

 // ShowImageScreen.kt
 @Composable
 fun ShowImageScreen(
     viewModel: ShowImageViewModel = viewModel(factory = ShowImageViewModel.Factory)
 ) { ... }

// ShowImageViewModel.kt
  class ShowImageViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
     private val imageUrl by lazy {
         savedStateHandle.get<String>("imageUrl")
     }
 }
In the above code I am explicitly passing in the url from Activity -> NavigationHost in the
onCreate
via the line
NavigationHost(imageUrl = imageUrl)
I am wondering if that is my only option or if the NavigationHost is somehow able to access the navArguments of the activity?
Would this be a viable solution?
Copy code
// NavigationHost.kt
 @Composable
 fun NavigationHost() {
     val navArguments = checkNotNull(LocalContext.current as Activity).navArguments<Bundle>())
     val imageUrl = navArguments.getString("image_url")
Answering my own question but the above ☝️ is working...
s

Stylianos Gakis

03/17/2024, 3:30 PM
Since it seems like you're doing activity navigation here, can you not just take the image_url in the activity itself directly, and just pass it down to your composable and avoid it having to have a route parameter in the first place? Since the route parameter in there isn't really used in any case right?
g

Gautam Lad

03/17/2024, 3:31 PM
Yes that's what I was doing and both do the same thing - I was just trying to avoid having to reference or pass in anything to the NavHost
s

Stylianos Gakis

03/17/2024, 3:32 PM
If you need to also then inside this separate activity have internal navigation where the url might be different, could you have two route definitions, one without the url, which takes it from the activity, and one with a route url which reads it from the parameters?
If you got rid of the activity completely and this was a normal nested navigation you'd just skip all the headache in the first place right, since you could just navigate with the right parameter being there and that fixes itself.
g

Gautam Lad

03/17/2024, 3:36 PM
The activity doesn't really nee the url it just needs to relay it to the composable to render with it so And yes, if the composable wasn't opening this route, then I could navigate to it with the param like any other composable... I guess what Im trying to get to here is, I wanted the activity pram to be somehow available to the composable being rendered with being very explicit about passing it to the NavHost (if that makes sense?)