[TIL] ๐ผ24/04/24๐ผ#Navigation in Jetpack Compose
Navigation in Jetpack Compose
- ์ค๋์ BMI ๊ณ์ฐ๊ธฐ navigation ๊ด๋ จ ์ฝ๋ ๋ฆฌํฉํ ๋ง์ ์งํํ๋ค.
- ๋จผ์ , Jetpack Compose์์์ Navigation์ ๋ํด ์์๋ณด์๋ค.
๐์ฐธ๊ณ ์๋ฃ
Navigation Component
- 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 ๊ณ์ฐ๊ธฐ ๋ฆฌํฉํ ๋ง
๋ฆฌํฉํ ๋ง ์
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
)
}
}
}
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()}")
}
}