Doug las
Doug las

Reputation: 3

Jetpack Compose NavGraphBuilder uses composable as a method parameter. How?

This is from an Android compass app project at https://github.com/AkarshGuptaa/Compass.git which compiles and runs without bugs

I'm wanting to know how compassComposable: @Composable () -> Unit is passed to the HomeScreen composable function when none of the calls to this function provide the "compassComposable" parameter

Here is a portion of the code

NavHost(
    modifier = modifier,
    navController = navController,
    startDestination = startDestination,
){
    composable(ScreenRoutes.Home.name){
        HomeScreen( // <- call to home screen (without compassComposable parameter)
        degrees = degrees,
        isMagneticFieldSensorPresent = isMagneticFieldSensorPresent,
        onMenuClick = { navController.navigate(ScreenRoutes.WidgetSelection.name )}
        ){..}
        ..       
    }

    composable(ScreenRoutes.WidgetSelection.name){ // but somehow this is correctly passed to the HomeScreen composable function HOW??
        ..
        WidgetScreen( ..
        )
    }
}

But the HomeScreen Composable fun has a compassComposable parameter that is never supplied.

@Composable
fun HomeScreen(
     modifier: Modifier = Modifier,
     degrees: Int, // observe this
     isMagneticFieldSensorPresent: Boolean,
     onMenuClick: () -> Unit = {},
     compassComposable: @Composable () -> Unit // Correctly points to the right navGraph composable but since it is never passed to the function when called, how does this happen?? 
     )  {
        ...
        compassComposable() // correctly displays the selected compass widget
        ..
        }


I've tried to trace it through the debugger but the "magic" seems to be happening in the background

Upvotes: 0

Views: 54

Answers (1)

gtxtreme
gtxtreme

Reputation: 3606

This is made possible with the help of trailing lambda syntax on Kotlin

Trailing lambda as the name says, is a lamda function that is the last (trailing) parameter in a function

So, let's say you have a function foo

fun foo(a:Int, b:Int, c:()->Unit){
   // Do something
}

If you notice, we have a lambda function as the last parameter, so you can call this like so, right?

fun main(){
  foo(a= 1, b=2 ,c ={
       // Do something 
        })
}

You can make this even more visually easy to read by the trailing lambda syntax like so

fun main(){
  foo(a=1, b=2){
    // This is provided to the parameter C 

    // Do something 
  }
}

Good read on the docs can be found here

Upvotes: 1

Related Questions