navigation 이동 Jetpack compose

매일 수정하는 GNOSS LV5·2022년 3월 16일
1

AndroidStudio

목록 보기
60/83
post-custom-banner

https://developer.android.com/jetpack/compose/navigation?hl=ko#deeplinks

build.gradle

dependencies {
    def nav_version = "2.4.1"

    implementation("androidx.navigation:navigation-compose:$nav_version")
}

  • 먼저 NavHost를 NavController를 단일 NavHost 컴포저블과 연결해야 합니다. 
    NavHost는 구성 가능한 대상을 지정하는 탐색 그래프와 NavController를 연결합니다.
    구성 가능한 대상은 컴포저블 간에 이동할 수 있어야 합니다. 컴포저블 간에 이동하면 NavHost의 콘텐츠가 자동으로 재구성됩니다. 탐색 그래프의 구성 가능한 대상은 각각 경로와 연결됩니다.
NavHost(navController = navController, startDestination = "profile") {
    composable("profile") { Profile(/*...*/) }
    composable("friendslist") { FriendsList(/*...*/) }
    /*...*/
}
  • navigation 이동은 기존의 jetpack navigation과 동일하게 navController.navigate를 이용하여 이동합니다.기존에 이동할때에는 해당 action에 해당하는 id를 넣어주는 대신 compose에서는 destination을 정해줍니다.
@Composable
fun Profile(navController: NavController) {
    /*...*/
    Button(onClick = { navController.navigate("friendslist") }) {
        Text(text = "Navigate next")
    }
    /*...*/
}
  • navigation이동을 할 때 이전에 사용했던 bundle처럼 argument를 넘겨줄 수 있습니다.

/**인자를 보내줄 떄 **/
navController.navigate("profile/user1234")

/**인자를 받을 때 **/
NavHost(startDestination = "profile/{userId}") {
    ...
    composable("profile/{userId}") {...}
}

NavHost(startDestination = "profile/{userId}") {
    ...
    composable(
        "profile/{userId}",
        arguments = listOf(navArgument("userId") { type = NavType.StringType })
    ) {...}
}

NavController는 Navigation 구성요소의 중심 API로, 스테이트풀(Stateful)이며 앱의 화면과 각 화면 상태를 구성하는 컴포저블의 백 스택을 추적합니다.

컴포저블에서 rememberNavController() 메서드를 사용하여 NavController를 만들 수 있습니다.

val navController = rememberNavController()

NagGraph분할

  • 그래프의 크기가 커질수록 그래프를 여러 메서드로 분할하는것을 추천하며 분할이 가능합니다.
fun NavGraphBuilder.loginGraph(navController: NavController) {
    navigation(startDestination = "username", route = "login") {
        composable("username") { ... }
        composable("password") { ... }
        composable("registration") { ... }
    }
}
  • 분할된 그래프들을 정리하려면 다음과 같이 합니다.
NavHost(navController, startDestination = "home") {
    communityGraph(navController)
    loginGraph(navController)
    setttingGraph(navController)
}

BottomNavigation

  • 먼저 BottomNavigation이 보여질 상위 계층 구조에서 NavController를 정의하고 그 안에서 바텀 네비게이션 아이템들을 넣습니다.
  • 하단 탐색 메뉴의 항목에 대한 정의를 합니다.
sealed class Screen(val route: String, @StringRes val resourceId: Int) {
    object Profile : Screen("profile", R.string.profile)
    object FriendsList : Screen("friendslist", R.string.friends_list)
}

val items = listOf(
   Screen.Profile,
   Screen.FriendsList,
)
  • BottomNavigation이 존재할 상위 계층 구조에서 정의합니다.
  • BottomNavigation 컴포저블에서 currentBackStackEntryAsState() 함수를 사용하여 현재 NavBackStackEntry를 가져옵니다. 이 항목을 통해 현재 NavDestination에 액세스할 수 있습니다. 그러면 중첩된 탐색을 사용하고 있는 경우를 처리하도록 hierarchy 도우미 메서드를 통해 항목의 경로와 현재 대상 및 그 상위 대상의 경로를 비교하여 각 BottomNavigationItem의 선택된 상태를 확인할 수 있습니다.
💡 `NavBackStackEntry` 는 백스택에 있는 항목들을 표현하기 위한 장치입니다. 이 객체를 통해 제공되어지는 Lifecycle, viewModel및 SavedState는 백 스택에서 대상의 수명과 같이 살아있습니다.
val navController = rememberNavController()
Scaffold(
  bottomBar = {
    BottomNavigation {
      val navBackStackEntry by navController.currentBackStackEntryAsState()
      val currentDestination = navBackStackEntry?.destination
      items.forEach { screen ->
        BottomNavigationItem(
          icon = { Icon(Icons.Filled.Favorite, contentDescription = null) },
          label = { Text(stringResource(screen.resourceId)) },
          selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
          onClick = {
            navController.navigate(screen.route) {
              // Pop up to the start destination of the graph to
              // avoid building up a large stack of destinations
              // on the back stack as users select items
              popUpTo(navController.graph.findStartDestination().id) {
                saveState = true
              }
              // Avoid multiple copies of the same destination when
              // reselecting the same item
              launchSingleTop = true
              // Restore state when reselecting a previously selected item
              restoreState = true
            }
          }
        )
      }
    }
  }
) { innerPadding ->
  NavHost(navController, startDestination = Screen.Profile.route, Modifier.padding(innerPadding)) {
    composable(Screen.Profile.route) { Profile(navController) }
    composable(Screen.FriendsList.route) { FriendsList(navController) }
  }
}
profile
러닝커브를 따라서 등반중입니다.
post-custom-banner

0개의 댓글