Nirali Pandya
Nirali Pandya

Reputation: 64

How to Navigate with Passing Arguments in Jetpack Compose?

Could someone provide a clear explanation or example code demonstrating how to navigate between destinations and pass arguments using Jetpack Compose?

In LoginPage1 when I click on button I want to go to next page with same param

//MainActivity.kt
Surface(
    modifier = Modifier.fillMaxSize(),
    color = MaterialTheme.colorScheme.background
) {
    LoginPage1(navController)
}

//LoginPage1
Button(
    onClick = { "go to next page" },
    shape = MaterialTheme.shapes.medium,
    colors = ButtonDefaults.buttonColors(orange),
) {
}

I tried this but I get a java.lang.NullPointerException:

Button(
    onClick = { navController.navigate("onboardingPage1") },
    shape = MaterialTheme.shapes.medium,
    colors = ButtonDefaults.buttonColors(orange),
)

Upvotes: 1

Views: 2406

Answers (2)

Cristan
Cristan

Reputation: 14125

Since navigation compose 2.7.0, you should now use routes. Example:

// Define a home destination that doesn't take any arguments
@Serializable
object Home

// Define a profile destination that takes an ID
@Serializable
data class Profile(val id: String)

// Now define your NavHost using type safe objects
NavHost(navController, startDestination = Home) {
    composable<Home> {
        HomeScreen(onNavigateToProfile = { id ->
            navController.navigate(Profile(id))
        })
    }
    composable<Profile> { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(profile)
    }
}

Getting the arguments in the ViewModel directly

You clean up the code some more by getting the arguments directly in the ViewModel:

class UserViewModel(
    savedStateHandle: SavedStateHandle,
    private val userInfoRepository: UserInfoRepository
) : ViewModel() {

    private val profile = savedStateHandle.toRoute<Profile>()

    // Fetch the relevant user information from the data layer,
    // ie. userInfoRepository, based on the passed userId argument
    private val userInfo: Flow<UserInfo> = userInfoRepository.getUserInfo(profile.id)

Upvotes: 2

Nirav Rangapariya
Nirav Rangapariya

Reputation: 409

First You need to declare param in destination route

object Constants {
    const val USER_DETAIL = "USER_DETAIL/{USER_ID}"
}

On Navigation Button Click

rootNavController.navigate(Constants.USER_DETAIL.replace("USER_ID",userId))

get param value in below way in Nav graph

@Composable
fun NavigationGraph(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = Screen.Login.route
    ){
        // .... 
        
        //.....
        composable(Constants.UserDetail) {
            val userId = it.arguments?.getString("USER_ID")?.toLong() ?: -1L
            UserDetailScreen(
                userId = userId
            )
        }
    }
}

Upvotes: 0

Related Questions