[TIL] ๐ŸŒผ24/04/24๐ŸŒผ#Navigation in Jetpack Compose

0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
86/100
post-thumbnail

[TIL] ๐ŸŒผ24/04/24๐ŸŒผ#Navigation in Jetpack Compose

  • ์˜ค๋Š˜์€ BMI ๊ณ„์‚ฐ๊ธฐ navigation ๊ด€๋ จ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง์„ ์ง„ํ–‰ํ–ˆ๋‹ค.
  • ๋จผ์ €, Jetpack Compose์—์„œ์˜ Navigation์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜๋‹ค.

๐Ÿ“Œ์ฐธ๊ณ ์ž๋ฃŒ

  • Navigation Graph
    • resource that collects all navigation-related data in one place
  • NavHost
    • unique composable
    • shows various composable destinations for Navigation Graph
    • each composable destination is associated with a route
    • content of the NavHost is recomposed when navigated between composables
  • NavController
    • central API for the Navigation component
    • stateful
    • keeps track of the back stack of composables

BMI ๊ณ„์‚ฐ๊ธฐ ๋ฆฌํŒฉํ† ๋ง

๋ฆฌํŒฉํ† ๋ง ์ „

  • MainActivity.kt
class MainActivity : AppCompatActivity() {
    private val mainViewModel by viewModels<MainViewModel>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BMIApp(mainViewModel = mainViewModel)
        }
    }
}
  • BMIApp.kt
    • screen ์‚ฌ์ด ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์„ ์œ„ํ•ด ViewModel ๊ฐ์ฒด ์ „๋‹ฌ
@Composable
fun BMIApp (mainViewModel:MainViewModel){
    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = "first_screen"
    ){
        composable("first_screen"){
            FirstScreen(navController = navController, mainViewModel = mainViewModel)
        }
        composable("result_screen"){
            ResultScreen(navController = navController, mainViewModel = mainViewModel)
        }
    }

๋ฆฌํŒฉํ† ๋ง ํ›„

  • BMIActivity.kt (rename MainActivity.kt -> BMIActivity.kt)
class BMIActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BMINavGraph()
        }
    }
}
  • BMINavGraph.kt
    • screen ์‚ฌ์ด ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์„ ์œ„ํ•ด argument ์‚ฌ์šฉ
@Composable
fun BMINavGraph(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: String = BMIDestinations.FIRST_ROUTE,
    navActions: BMINavigationActions = remember(navController) {
        BMINavigationActions(navController)
    }
) {
    NavHost(
        navController = navController,
        startDestination = startDestination,
        modifier = modifier
    ) {
        composable(BMIDestinations.FIRST_ROUTE) {
            FirstScreen(
                navToResult = { height:Float, weight:Float ->
                    navActions.navigateToResult(height, weight)
                }
            )
        }
        composable(
            BMIDestinations.RESULT_ROUTE,
            arguments = listOf(
                navArgument(HEIGHT_ARG) {
                    type = NavType.FloatType; defaultValue = 0.0
                },
                navArgument(WEIGHT_ARG) {
                    type = NavType.FloatType; defaultValue = 0.0
                },
            )
        ) {
            ResultScreen(
                navToFirst = { navActions.navigateToFirst() },
                height = it.arguments?.getFloat(HEIGHT_ARG)?:0.0F,
                weight = it.arguments?.getFloat(WEIGHT_ARG)?:0.0F
            )
        }
    }
}
  • BMINavigation.kt
private object BMIScreens{
    const val FIRST_SCREEN = "first_screen"
    const val RESULT_SCREEN = "result_screen"
}

object BMIDestinationArgs{
    const val HEIGHT_ARG = "height"
    const val WEIGHT_ARG = "weight"
}

object BMIDestinations{
    const val FIRST_ROUTE = FIRST_SCREEN
    const val RESULT_ROUTE = "$RESULT_SCREEN/{$HEIGHT_ARG}/{$WEIGHT_ARG}"
}

class BMINavigationActions(private val navController: NavHostController) {
    fun navigateToFirst(){
        navController.navigate(FIRST_SCREEN){
            popUpTo(navController.graph.findStartDestination().id){
                inclusive = true
            }
        }
    }

    fun navigateToResult(height:Float, weight:Float){
        navController.navigate("$RESULT_SCREEN/${height.toString()}/${weight.toString()}")
    }
}

0๊ฐœ์˜ ๋Œ“๊ธ€