{"id":45742,"date":"2021-11-22T19:25:14","date_gmt":"2021-11-22T10:25:14","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=45742"},"modified":"2021-11-22T19:25:14","modified_gmt":"2021-11-22T10:25:14","slug":"jetpack-compose-navigation-%eb%84%a4%eb%b9%84%ea%b2%8c%ec%9d%b4%ec%85%98%ec%9c%bc%eb%a1%9c-%eb%a7%88%ec%9d%b4%ea%b7%b8%eb%a0%88%ec%9d%b4%ec%85%98","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=45742","title":{"rendered":"Jetpack Compose Navigation &#8211; \ub124\ube44\uac8c\uc774\uc158\uc73c\ub85c \ub9c8\uc774\uadf8\ub808\uc774\uc158"},"content":{"rendered":"\n<p>Rally\ub294 \ucd08\uae30\uc5d0 Navigation\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uae30\uc874 \uc571\uc774\ub2e4. \ub124\ube44\uac8c\uc774\uc158\uc73c\ub85c \ub9c8\uc774\uadf8\ub808\uc774\uc158\ud558\ub294 \uba87 \uac00\uc9c0 \ub2e8\uacc4\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<ol><li>\ub124\ube44\uac8c\uc774\uc158 \uc758\uc874\uc131 \ucd94\uac00<\/li><li>NavController \ubc0f NavHost \uc124\uc815\ud558\uae30<\/li><li>\ubaa9\uc801\uc9c0 \ub8e8\ud2b8 \uc900\ube44\ud558\uae30<\/li><li>\uae30\uc874 \ubaa9\uc801\uc9c0 \uba54\ucee4\ub2c8\uc998\uc744 \ub124\ube44\uac8c\uc774\uc158 \ub8e8\ud2b8\ub85c \ubcc0\uacbd\ud558\uae30<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">\ub124\ube44\uac8c\uc774\uc158 \uc758\uc874\uc131 \ucd94\uac00\ud558\uae30<\/h2>\n\n\n\n<p>app\/build.gradle \ucc3e\uc544\uc11c \uc5f4\uc790. dependencies \ubd80\ubd84\uc5d0 navigation-compose \uc758\uc874\uc131\uc744 \ucd94\uac00\ud558\uc790.<\/p>\n\n\n\n<p>\ucd5c\uc2e0\ubc84\uc804\uc740 <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/navigation\">\uacf5\uc2dd\ubb38\uc11c<\/a>\ub97c \ucc38\uc870\ud558\uc790<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dependencies {\n  implementation \"androidx.navigation:navigation-compose:2.4.0-beta04\"\n  ...\n}<\/pre>\n\n\n\n<p>\uc774\uc81c \ud504\ub85c\uc81d\ud2b8\ub97c sync\ud558\uba74 \ucef4\ud3ec\uc988\uc5d0\uc11c \ub124\ube44\uac8c\uc774\uc158\uc744 \uc0ac\uc6a9\ud560 \uc900\ube44\uac00 \ub418\uc5c8\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">NavController \uc124\uc815\ud558\uae30<\/h2>\n\n\n\n<p>\ucef4\ud3ec\uc988\uc5d0\uc11c \ub124\ube44\uac8c\uc774\uc158\uc744 \uc0ac\uc6a9\ud560 \ub54c NavController\ub294 \uc911\uc2ec\uc774 \ub418\ub294 \ucef4\ud3ec\ub10c\ud2b8\ub2e4. \ubc31 \uc2a4\ud0dd \ud56d\ubaa9\uc744 \ucd94\uc801\ud558\uace0, \uc2a4\ud0dd\uc744 \uc55e\uc73c\ub85c \uc774\ub3d9\ud558\uace0, \ubc31 \uc2a4\ud0dd \uc870\uc791\uc744 \ud65c\uc131\ud654\ud558\uace0, \ud654\uba74 \uc0c1\ud0dc(Screen states) \uac04 \ub124\ube44\uac8c\uc774\ud305 \ud55c\ub2e4. NavController\ub294 \ub124\ube44\uac8c\uc774\uc158\uc758 \uc911\uc2ec\uc774\uae30 \ub54c\ubb38\uc5d0, \ubaa9\uc801\uc9c0\ub85c \uc774\ub3d9\ud558\ub824\uba74 NavController\ub97c \uba3c\uc800 \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<p>\uc6b0\ub9ac\ub294 \ucef4\ud3ec\uc988\ub0b4\uc5d0\uc11c NavController\uc758 \ud558\uc704 \ud074\ub798\uc2a4\uc778 NavHostController\ub85c \uc791\uc5c5\ud558\uace0 \uc788\ub2e4. rememberNavController() \ud568\uc218\ub97c \uc0ac\uc6a9\ud558\uc5ec NavController \uc5bb\uc790. \uc774\ub294 NavController\ub97c \uc0dd\uc131\ud558\uace0 \ucef4\ud3ec\uc9c0\uc158\ub0b4\uc5d0 \uc800\uc7a5\ud55c\ub2e4. remember Savable\uc744 \uc0ac\uc6a9\ud558\uba74 \uad6c\uc131 \ubcc0\uacbd(\uc608:\ud654\uba74\ud68c\uc804)\uc5d0\uc11c\ub3c4 NavController\uac00 \uc0b4\uc544\ub0a8\ub294\ub2e4. NavController\ub294 \ub2e8\uc77c NavHost \ucef4\ud3ec\uc800\ube14\uacfc \uc5f0\uad00\ub418\uc5b4\uc788\ub2e4. NavHost\ub294 NavController\ub97c \ucef4\ud3ec\uc800\ube14 \ubaa9\uc801\uc9c0\ub4e4\uc774 \uba85\uc2dc\ub418\uc5b4\uc788\ub294 \ub124\ube44\uac8c\uc774\uc158 \uadf8\ub798\ud504\uc640 \uc5f0\uacb0\ud55c\ub2e4.<\/p>\n\n\n\n<p>\uc774 \ucf54\ub4dc\ub7a9\uc5d0\uc11c\ub294 RallyApp\ub0b4\uc5d0\uc11c NavController\ub97c \uc5bb\uace0, \uc800\uc7a5\ud55c\ub2e4. NavController\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc804\uccb4\uc5d0 \ub300\ud55c \ucd5c\uc0c1\uc704(root) \ucef4\ud3ec\uc800\ube14\uc774\ub2e4. RallyActivity.kt\uc5d0\uc11c \uc774\ub97c \ucc3e\uc744 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Composable\nfun RallyApp() {\n\u00a0 \u00a0 RallyTheme {\n\u00a0 \u00a0 \u00a0 \u00a0 val allScreens = RallyScreen.values().toList()\n\u00a0 \u00a0 \u00a0 \u00a0 var currentScreen by rememberSaveable { mutableStateOf(RallyScreen.Overview) }\n<strong>\u00a0 \u00a0 \u00a0 \u00a0 val navController = rememberNavController()<\/strong>\n\u00a0 \u00a0 \u00a0 \u00a0 Scaffold(...\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\ubaa9\uc801\uc9c0\ub97c \uc704\ud55c \ub8e8\ud2b8 \uc900\ube44\ud558\uae30(Prepare routes for destinations)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\uac1c\uc694(Overview)<\/h3>\n\n\n\n<p>Rally \uc571\uc740 3\uac00\uc9c0 \ud654\uba74\uc744 \uac16\uace0 \uc788\ub2e4.<\/p>\n\n\n\n<ol><li>\uac1c\uc694(Overview) &#8211; \uc804\uccb4 \uae08\uc735 \uac70\ub798 \uac1c\uc694 \ubc0f \uc54c\ub9bc<\/li><li>\uacc4\uc88c(Accounts) &#8211; \uae30\uc874 \uacc4\uc88c\uc5d0 \ub300\ud55c \uc774\ud574<\/li><li>\uccad\uad6c\uc11c(Bills) &#8211; \uc608\uc815\ub41c \ube44\uc6a9<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><img decoding=\"async\" alt=\"Screenshot of the overview screen containing information on Alerts, Accounts and Bills.\" src=\"https:\/\/developer.android.com\/codelabs\/jetpack-compose-navigation\/img\/87e7dfa76ef51d50.png?hl=ko\" style=\"width: 250px;\"><\/td><td><img decoding=\"async\" alt=\"Screenshot of the Accounts Screen, containing information on several accounts.\" src=\"https:\/\/developer.android.com\/codelabs\/jetpack-compose-navigation\/img\/a7c8a51fe2503409.png?hl=ko\" style=\"width: 250px;\"><\/td><td><img decoding=\"async\" alt=\"Screenshot of the Bills Screen, containing information on several outgoing bills.\" src=\"https:\/\/developer.android.com\/codelabs\/jetpack-compose-navigation\/img\/9e4c38a6bff0fdbb.png?hl=ko\" style=\"width: 250px;\"><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\ubaa8\ub4e0 \uc138 \ud654\uba74\ub4e4\uc740 \ucef4\ud3ec\uc800\ube14\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9cc\ub4e4\uc5b4\uc84c\ub2e4. RallyScreen.kt\ub97c \uc0b4\ud3b4\ubcf4\uc790. \uc774 \ud30c\uc77c\uc5d0 \uc138 \ud654\uba74\uc740 \uc774 \uc120\uc5b8\ub418\uc5b4\uc788\ub2e4. \ub098\uc911\uc5d0 Overview\ub97c \uc2dc\uc791 \ubaa9\uc801\uc9c0\ub85c\ud558\uc5ec, \uc774 \uc138\ud654\uba74\ub4e4\uc744 \ub124\ube44\uac8c\uc774\uc158\uc758 \ubaa9\uc801\uc9c0\ub85c \ub9e4\ud551\ud560 \uac83\uc774\ub2e4. \ub610\ud55c RallyScreen\uc73c\ub85c\ubd80\ud130 \ucef4\ud3ec\uc800\ube14\uc744 NavHost\ub85c \uc774\ub3d9\uc2dc\ud0ac \uac83\uc774\ub2e4. \uc9c0\uae08 \ub2f9\uc7a5\uc740 RallyScreen\uc744 \uc190\ub300\uc9c0 \uc54a\uc740\ucc44\ub85c \uadf8\ub0e5 \ub450\uc790.<\/p>\n\n\n\n<p>\ucef4\ud3ec\uc988\ub0b4\uc5d0\uc11c \ub124\ube44\uac8c\uc774\uc158\uc744 \uc0ac\uc6a9\ud560 \ub54c, \uacbd\ub85c(\ub8e8\ud2b8)\ub294 \ubb38\uc790\uc5f4\ub85c \ud45c\ud604\ub41c\ub2e4. \uc774\ub7ec\ud55c \ubb38\uc790\uc5f4\ub4e4\uc744 URL \ub610\ub294 \ub525\ub9c1\ud06c\ub77c\uace0 \uc0dd\uac01\ud560 \uc218 \uc788\ub2e4. \uc774 \ucf54\ub4dc\ub7a9\uc5d0\uc11c\ub294 \uac01 RallyScreen \uc544\uc774\ud15c\uc744 \uacbd\ub85c\ub85c\ud558\uc5ec name\uc18d\uc131\uc744 \uc0ac\uc6a9\ud574\ubcf4\uc790.  \uc608\ub97c\ub4e4\uba74 RallyScreen.Overview.name \uc774\ub77c\uace0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\uc900\ube44(Preparation)<\/h3>\n\n\n\n<p>RallyActivity.kt\uc5d0\uc11c RallyApp \ucef4\ud3ec\uc800\ube14\ub85c \ub3cc\uc544\uc628 \ub4a4, \ud654\uba74\uc758 \ucee8\ud150\uce20\ub97c \ud3ec\ud568\ud558\uace0 \uc788\ub294 Box\ub97c \uc0c8\ub85c \uc0dd\uc131\ud55c NavHost\ub85c \uad50\uccb4\ud558\uc790. \uc774\uc804 \ub2e8\uacc4\uc5d0\uc11c \uc6b0\ub9ac\uac00 \uc0dd\uc131\ud55c navController\ub97c \uc804\ub2ec\ud55c\ub2e4. NavHost\ub294 \ub610\ud55c startDestination\uc774 \ud544\uc694\ud558\ub2e4. RallyScreen.Overview.name\uc73c\ub85c \uc124\uc815\ud558\uc790. \ub610\ud55c Modifier\ub97c \uc0dd\uc131\ud558\uc5ec padding\uc744 \uc801\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d NavHost\uc5d0 \uc804\ub2ec\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Scaffold(...) { innerPadding ->\n\u00a0 \u00a0 \u00a0 \u00a0 <strong>NavHost(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 navController = navController,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 startDestination = RallyScreen.Overview.name,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 modifier = Modifier.padding(innerPadding)\n\u00a0 \u00a0 \u00a0 \u00a0 ) { ... }<\/strong><\/code><\/pre>\n\n\n\n<p>\uc774\uc81c \ub124\ube44\uac8c\uc774\uc158 \uadf8\ub798\ud504\ub97c \uc815\uc758 \ud560 \uc218 \uc788\ub2e4. NavHost\uac00 \uc774\ub3d9\ud560 \uc218 \uc788\ub294 \ubaa9\uc801\uc9c0\ub4e4\uc740 \ub2e4\ub978 \ubaa9\uc801\uc9c0\ub4e4\uc744 \uc218\uc6a9\ud560 \uc900\ube44\uac00 \ub418\uc5c8\ub2e4. NavHost\uc758 \ub9c8\uc9c0\ub9c9 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \uc81c\uacf5\ub418\ub294 NavGraphBuilder\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774 \uc791\uc5c5\uc744 \uc218\ud589\ud55c\ub2e4. NavGraphBuilder\ub294 \ud6c4\ud589 \ub78c\ub2e4\uc2dd \ud45c\ud604\uc73c\ub85c \ubaa9\uc801\uc9c0\ub97c \uc120\uc5b8\ud560 \uc218 \uc788\ub2e4. Navigation Compose \uc544\ud2f0\ud329\ud2b8\ub294 NavGraphBuilder.composable \ud655\uc7a5 \ud568\uc218\ub97c \uc81c\uacf5\ud55c\ub2e4. \uc774 \ud568\uc218\ub97c \uadf8\ub798\ud504\uc5d0\uc11c \ubaa9\uc801\uc9c0\ub97c \uc774\ub3d9\uc744 \uc815\uc758\ud558\ub294 \ub370 \uc0ac\uc6a9\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NavHost(\n\u00a0 \u00a0 navController = navController,\n\u00a0 \u00a0 startDestination = RallyScreen.Overview.name,\n\u00a0 \u00a0 modifier = Modifier.padding(innerPadding)\n\n) { <strong>\n\u00a0 \u00a0 composable(RallyScreen.Overview.name) { ... }<\/strong>\n}<\/code><\/pre>\n\n\n\n<p>\uc9c0\uae08 \ub2f9\uc7a5\uc740 \ud654\uba74 \uc774\ub984\uc744 \ucef4\ud3ec\uc800\ube14\uc758 \ub0b4\uc6a9\uc73c\ub85c Text\ub97c \uc784\uc2dc \uc124\uc815\ud55c\ub2e4. \ub2e4\uc74c \ub2e8\uacc4\uc5d0\uc11c\ub294 \uae30\uc874 \ucef4\ud3ec\uc800\ube14\uc744 \uc0ac\uc6a9\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NavHost(\n\u00a0 \u00a0 navController = navController,\n\u00a0 \u00a0 startDestination = RallyScreen.Overview.name\n\u00a0 \u00a0 modifier = Modifier.padding(innerPadding)\n) { \n\u00a0 \u00a0 composable(RallyScreen.Overview.name) {\n<strong>\u00a0 \u00a0 \u00a0 Text(text = RallyScreen.Overview.name)<\/strong>\n\u00a0 \u00a0 }\n\n\u00a0 \u00a0 \/\/ TODO: \ub2e4\ub978 \ub450\uac1c\uc758 \ud654\uba74\uc744 \ucd94\uac00\ud558\uc790\n}<\/code><\/pre>\n\n\n\n<p>\uc774\uc81c Scaffold\uc5d0\uc11c currentScreen.content \ud638\ucd9c\uc744 \uc81c\uac70\ud558\uace0 \uc571\uc744 \uc2e4\ud589\ud558\uc790. \uc2dc\uc791 \ubaa9\uc801\uc9c0\uc758 \uc774\ub984\uacfc \uc704\uc758 \ud0ed\uc774 \ud45c\uc2dc\ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\ucd5c\uc885\uc801\uc778 \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NavHost(<br>&nbsp; &nbsp; navController = navController,<br>&nbsp; &nbsp; startDestination = RallyScreen.Overview.name,<br>&nbsp; &nbsp; modifier = Modifier.padding(innerPadding)<br>) {<br>&nbsp; &nbsp; composable(RallyScreen.Overview.name) { <br>&nbsp; &nbsp; &nbsp; Text(RallyScreen.Overview.name)<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; composable(RallyScreen.Accounts.name) {<br>&nbsp; &nbsp; &nbsp; &nbsp; Text(RallyScreen.Accounts.name) <br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; composable(RallyScreen.Bills.name) { <br>&nbsp; &nbsp; &nbsp; &nbsp; Text(RallyScreen.Bills.name) <br>&nbsp; &nbsp; }<br>}<\/code><\/pre>\n\n\n\n<p>NavHost\ub294 \uc774\uc81c Scaffold \ub0b4\uc758 Box\ub97c \ub300\uccb4\ud560 \uc218 \uc788\ub2e4. innerPadding\uc744 \uadf8\ub300\ub85c \uc720\uc9c0\ud558\ub824\uba74 Modifier\ub97c NavHost\uc5d0 \uc804\ub2ec\ud558\uc790.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Composable\nfun RallyApp() {\n\u00a0 \u00a0 RallyTheme {\n\u00a0 \u00a0 \u00a0 \u00a0 val allScreens = RallyScreen.values().toList()\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ FIXME: \uc774 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub294 \ub098\uc911\uc5d0 \uc81c\uac70 \ub41c\ub2e4.\n\u00a0 \u00a0 \u00a0 \u00a0 var currentScreen by rememberSaveable {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mutableStateOf(RallyScreen.Overview)\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 val navController = rememberNavController()\n\u00a0 \u00a0 \u00a0 \u00a0 Scaffold(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 topBar = {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 RallyTabRow(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 allScreens = allScreens,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 onTabSelected = { screen -> currentScreen = screen },\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 currentScreen = currentScreen\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 )\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 ) { innerPadding ->\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 NavHost(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 navController = navController,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 startDestination = RallyScreen.Overview.name,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <strong>modifier = Modifier.padding(innerPadding)<\/strong>) {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n\n\n\n<p>\uc774 \uc2dc\uc810\uc5d0\uc11c Top bar\ub294 \uc544\uc9c1 \uc5f0\uacb0\ub418\uc9c0 \uc54a\uc558\uc73c\ubbc0\ub85c, \ud0ed\uc744 \ud074\ub9ad\ud574\ub3c4 \ud45c\uc2dc\ub41c \ucef4\ud3ec\uc800\ube14\uc774 \ubcc0\uacbd\ub418\uc9c0 \uc54a\ub294\ub2e4. \ub2e4\uc74c \ub2e8\uacc4\uc5d0\uc11c \uc774\ub97c \ucc98\ub9ac\ud558\uc790.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\ub124\ube44\uac8c\uc774\uc158 \ubc14 \uc0c1\ud0dc \ubcc0\uacbd\uc744 \uc644\uc804\ud788 \ud1b5\ud569\ud558\uae30<\/h2>\n\n\n\n<p>\uc774 \ub2e8\uacc4\uc5d0\uc11c\ub294 RallyTabRow\ub97c \uc5f0\uacb0\ud558\uace0, \ud604\uc7ac \uc218\ub3d9 \ub124\ube44\uac8c\uc774\uc158 \ucf54\ub4dc\ub97c \uc0ad\uc81c\ud558\uac8c \ub41c\ub2e4. \uc774 \ub2e8\uacc4\ub97c \uc644\ub8cc\ud558\uba74 \ub124\ube44\uac8c\uc774\uc158 \ucef4\ud3ec\ub10c\ud2b8\uac00 \uc644\uc804\ud788 \ub77c\uc6b0\ud305(\ubaa9\uc801\uc9c0 \uc774\ub3d9)\uc744 \ucc98\ub9ac\ud55c\ub2e4.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Note: \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \uac00\ub2a5\ud558\uac8c \ub9cc\ub4e4\ub824\uba74, navController\ub97c \uc804\ub2ec\ud558\uc9c0 \uc54a\ub294 \uac83\uc774 \uc88b\ub2e4. \uc774 \ucf54\ub4dc\ub7a9\uc5d0\uc11c\ub294 \ub2e8\uc77c \ucc45\uc784 \uc9c0\uc810\uc5d0\uc11c \uc774\ub3d9\ud560 \uc218 \uc788\ub3c4\ub85d \ucf5c\ubc31\uc744 \uc81c\uacf5\ud55c\ub2e4.<\/p><\/blockquote>\n\n\n\n<p>RallyActivity\uc5d0\uc11c \ud0ed\uc744 \ud074\ub9ad\ud558\uba74, RallyTabRow \ucef4\ud3ec\uc800\ube14\uc5d0 onTabSelected\ub77c\ub294 \ucf5c\ubc31\uc774 \uc218\uc2e0\ub428\uc744 \uc54c \uc218 \uc788\ub2e4. \uc120\ud0dd\ud55c \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud558\uae30 \uc704\ud574 navController\ub97c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ucf54\ub4dc\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\uc790.<\/p>\n\n\n\n<p>\ub2e4\uc74c\uc740 \ub124\ube44\uac8c\uc774\uc158\uc744 \uc0ac\uc6a9\ud558\uc5ec, TabRow\ub97c \ud1b5\ud574 \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud558\ub294 \ucf54\ub4dc\ub97c \ubcf4\uc5ec\uc900\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Composable\nfun RallyApp() {\n\u00a0 \u00a0 RallyTheme {\n\u00a0 \u00a0 \u00a0 \u00a0 val allScreens = RallyScreen.values().toList()\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ FIXME: \uc774\ub294 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub85c \ub098\uc911\uc5d0 \uc81c\uac70 \ud55c\ub2e4.\n\u00a0 \u00a0 \u00a0 \u00a0 var currentScreen by rememberSaveable {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mutableStateOf(RallyScreen.Overview)\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 val navController = rememberNavController()\n\u00a0 \u00a0 \u00a0 \u00a0 Scaffold(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 topBar = {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 RallyTabRow(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 allScreens = allScreens,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <strong>onTabSelected = { screen ->\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 navController.navigate(screen.name)<\/strong>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <strong>}<\/strong>,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 currentScreen = currentScreen,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 )\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }<\/code><\/pre>\n\n\n\n<p>\uc774 \ubcc0\uacbd\uc73c\ub85c currentScreen\uc740 \ub354 \uc774\uc0c1 \uc5c5\ub370\uc774\ud2b8\ub418\uc9c0 \uc54a\ub294\ub2e4. \uc989, \uc120\ud0dd\ud55c \uc544\uc774\ud15c\uc758 \ud655\uc7a5 \ubc0f \ucd95\uc18c\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4. \uc774 \ub3d9\uc791\uc744 \ub2e4\uc2dc \ud65c\uc131\ud654\ud558\ub824\uba74 currentScreen \uc18d\uc131\ub3c4 \uc5c5\ub370\uc774\ud2b8\ud574\uc57c \ud55c\ub2e4. \ub2e4\ud589\ud788\ub3c4 Navigation\uc740 \ubc31 \uc2a4\ud0dd\uc744 \uc720\uc9c0\ud558\uace0, \ud604\uc7ac \ubc31 \uc2a4\ud0dd \ud56d\ubaa9\uc744 State\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4. \uc774 State\ub97c \uc0ac\uc6a9\ud558\uba74 \ubc31 \uc2a4\ud0dd\uc758 \ubcc0\uacbd \uc0ac\ud56d\uc5d0 \ub300\uc751\ud560 \uc218 \uc788\ub2e4. \uacbd\ub85c\uc5d0 \ub300\ud55c \ud604\uc7ac \ubc31 \uc2a4\ud0dd \ud56d\ubaa9\uc744 \ucffc\ub9ac\ud560 \uc218\ub3c4 \uc788\ub2e4.<\/p>\n\n\n\n<p>TabRow \ud654\uba74 \uc120\ud0dd\uc744 Navigation\uc73c\ub85c \ub9c8\uc774\uadf8\ub808\uc774\uc158\ud558\ub294 \uc791\uc5c5\uc744 \ub9c8\uce58\ub824\uba74, \ub2e4\uc74c\uacfc \uac19\uc774 \ub124\ube44\uac8c\uc774\uc158 \ubc31\uc2a4\ud0dd\uc744 \uc0ac\uc6a9\ud558\ub3c4\ub85d currentScreen\uc744 \uc5c5\ub370\uc774\ud2b8\ud558\uc790.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Composable\nfun RallyApp() {\n\u00a0 \u00a0 RallyTheme {\n\u00a0 \u00a0 \u00a0 \u00a0 val allScreens = RallyScreen.values().toList()\n\u00a0 \u00a0 \u00a0 \u00a0 val navController = rememberNavController()\n\u00a0 \u00a0 \u00a0 \u00a0 <strong>val backstackEntry = navController.currentBackStackEntryAsState()<\/strong>\n\u00a0 \u00a0 \u00a0 \u00a0 <strong>val currentScreen = RallyScreen.fromRoute(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 backstackEntry.value?.destination?.route\n\u00a0 \u00a0 \u00a0 \u00a0 )<\/strong>\n\u00a0 \u00a0 \u00a0 \u00a0 ...\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n\n\n\n<p>\uc774 \uc2dc\uc810\uc5d0\uc11c \uc571\uc744 \uc2e4\ud589\ud558\uba74, \ud0ed\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud654\uba74 \uac04\uc5d0 \uc804\ud658\ud560 \uc218 \uc788\uc9c0\ub9cc \ud45c\uc2dc\ub418\ub294 \uac83\uc740 \ud654\uba74 \uc774\ub984\ubfd0\uc774\ub2e4. \ud654\uba74\uc774 \ud45c\uc2dc\ub418\uae30 \uc804\uc5d0 RallyScreen\uc744 \ub124\ube44\uac8c\uc774\uc158\uc73c\ub85c \ub9c8\uc774\uadf8\ub808\uc774\uc158\ud574\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">RallyScreen\uc744 \ub124\ube44\uac8c\uc774\uc158\uc73c\ub85c \ub9c8\uc774\uadf8\ub808\uc774\uc158\ud558\uae30<\/h2>\n\n\n\n<p>\uc774 \ub2e8\uacc4\ub97c \uc644\ub8cc\ud558\uba74 \ucef4\ud3ec\uc800\ube14\uc774 RallyScreen \uc5f4\uac70\ud615\uc5d0\uc11c \uc644\uc804\ud788 \ubd84\ub9ac\ub418\uace0 NavHost\ub85c \uc774\ub3d9\ub41c\ub2e4. RallyScreen\uc740 \ud654\uba74\uc758 \uc544\uc774\ucf58\uacfc \uc81c\ubaa9\uc744 \uc81c\uacf5\ud558\uae30 \uc704\ud574\uc11c\ub9cc \uc874\uc7ac\ud55c\ub2e4.<\/p>\n\n\n\n<p>RallyScreen.kt\ub97c \uc5f4\uace0, \uac01 \ud654\uba74\uc758 body \uad6c\ud604\uc744 RallyApp\uc758 NavHost \ub0b4\uc758 \ud574\ub2f9 \ucef4\ud3ec\uc800\ube14\ub85c \uc774\ub3d9\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NavHost(\n\u00a0 \u00a0 navController = navController,\n\u00a0 \u00a0 startDestination = Overview.name,\n\u00a0 \u00a0 modifier = Modifier.padding(innerPadding)\n) {\n\u00a0 \u00a0 \n\u00a0 \u00a0 composable(Overview.name) {\n\u00a0 \u00a0 \u00a0 \u00a0 <strong>OverviewBody()<\/strong>\n\u00a0 \u00a0 }\n\u00a0 \u00a0 composable(Accounts.name) {\n\u00a0 \u00a0 \u00a0 \u00a0 <strong>AccountsBody(accounts = UserData.accounts)<\/strong>\n\u00a0 \u00a0 }\n\u00a0 \u00a0 composable(Bills.name) {\n\u00a0 \u00a0 \u00a0 \u00a0 <strong>BillsBody(bills = UserData.bills)<\/strong>\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n\n\n\n<p>\uc774 \uc2dc\uc810\uc5d0\uc11c, \ub2e4\uc74c \ucf54\ub4dc\ub97c \ub0a8\uae38 RallyScreen\uc5d0\uc11c \ucf58\ud150\uce20 \ud568\uc218, body \ub9e4\uac1c\ubcc0\uc218 \ubc0f \uadf8 \uc0ac\uc6a9\ubc95\ub4e4\uc744 \uc548\uc804\ud558\uac8c \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>enum class RallyScreen(<br>&nbsp; &nbsp; val icon: ImageVector,<br>) {<br>&nbsp; &nbsp; Overview(<br>&nbsp; &nbsp; &nbsp; &nbsp; icon = Icons.Filled.PieChart,<br>&nbsp; &nbsp; ),<br>&nbsp; &nbsp; Accounts(<br>&nbsp; &nbsp; &nbsp; &nbsp; icon = Icons.Filled.AttachMoney,<br>&nbsp; &nbsp; ),<br>&nbsp; &nbsp; Bills(<br>&nbsp; &nbsp; &nbsp; &nbsp; icon = Icons.Filled.MoneyOff,<br>&nbsp; &nbsp; );<br><br>&nbsp; &nbsp; companion object {<br>&nbsp; &nbsp; &nbsp; &nbsp; ...<br>&nbsp; &nbsp; }<br>}<\/code><\/pre>\n\n\n\n<p>\uc571\uc744 \ub2e4\uc2dc \uc2e4\ud589\ud558\uba74, \uc6d0\ub798\ub098\uc624\ub358 3\uac1c\uc758 \ud654\uba74\uc774 \ud45c\uc2dc\ub418\uace0, TabRow\ub97c \ud1b5\ud574 \ud654\uba74\uac04 \uc774\ub3d9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Note: \uc704\uc758 \ubcc0\uacbd \uc0ac\ud56d\uc73c\ub85c \uc774\uc81c \ub124\ube44\uac8c\uc774\uc158 \ucef4\ud3ec\ub10c\ud2b8\ub97c \ud1b5\ud574 \ub4a4\ub85c<em>(back)<\/em>\uc774\ub3d9\uc774 \uc9c0\uc6d0\ub429\ub2c8\ub2e4. \ud654\uba74 \uc0ac\uc774\ub97c \uc804\ud658\ud55c \ub2e4\uc74c back \ubc84\ud2bc\uc744 \ub204\ub974\uba74 \uc2a4\ud0dd\uc774 \ud31d\uc5c5\ub418\uace0, \uc774\uc804 \ubaa9\uc801\uc9c0\ub85c \uc774\ub3d9\ud55c\ub2e4.<\/p><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">OverviewScreen\uc5d0\uc11c \ud074\ub9ad \ud65c\uc131\ud654\ud558\uae30<\/h2>\n\n\n\n<p>\uc774 \ucf54\ub4dc\ub7a9\uc5d0\uc11c OverviewBody\uc758 \ud074\ub9ad \uc774\ubca4\ud2b8\ub294 \ucc98\uc74c\uc5d0 \ubb34\uc2dc\ub418\uc5c8\ub2e4. \uc774\ub294 &#8220;SEE ALL&#8221; \ubc84\ud2bc\uc744 \ud074\ub9ad\ud560 \uc218 \uc788\uc5c8\uc9c0\ub9cc, \uc544\ubb34\ub370\ub3c4 \uac00\uc9c0 \uc54a\uc558\uc74c\uc744 \uc758\ubbf8\ud55c\ub2e4.<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/developer.android.com\/codelabs\/jetpack-compose-navigation\/img\/29dc1e26aa33faf3.gif?hl=ko\" alt=\"Screen recording of the overview screen, scrolling to eventual click destinations, and attempting to click. Clicks don't work as they aren't implemented yet.\" width=\"379\" height=\"800\"\/><\/figure>\n\n\n\n<p>\uc790 \uc774\uc81c \uace0\uccd0\ubcf4\uc790!<\/p>\n\n\n\n<p>OverviewBody\ub294 \ud074\ub9ad \uc774\ubca4\ud2b8\uc5d0 \ub300\ud55c \ucf5c\ubc31\uc73c\ub85c \uc5ec\ub7ec \ud568\uc218\ub97c \ud5c8\uc6a9\ud560 \uc218 \uc788\ub2e4. onClickSeeAllAccounts \ubc0f onClickSeeAllBills\ub97c \uad6c\ud604\ud558\uc5ec \uad00\ub828 \ubaa9\uc801\uc9c0\ub85c \uc774\ub3d9\ud574 \ubcf4\uc790.<\/p>\n\n\n\n<p>&#8220;SEE ALL&#8221; \ubc84\ud2bc\uc744 \ud074\ub9ad\ud560 \ub54c \uc774\ub3d9\uc744 \ud65c\uc131\ud654\ud558\ub824\uba74, navController\ub97c \uc0ac\uc6a9\ud558\uc5ec Account \ub610\ub294 Bill \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud55c\ub2e4. RallyActivity.kt\ub97c \uc5f4\uace0 NavHost\uc5d0\uc11c OverviewBody\ub97c \ucc3e\uc544 navigate \ud638\ucd9c\uc744 \ucd94\uac00\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OverviewBody(\n<strong>\u00a0 \u00a0 onClickSeeAllAccounts = { navController.navigate(Accounts.name) },\n\u00a0 \u00a0 onClickSeeAllBills = { navController.navigate(Bills.name) },<\/strong>\n)<\/code><\/pre>\n\n\n\n<p>\uc774\uc81c OverviewBody\uc5d0 \ub300\ud55c \ud074\ub9ad \uc774\ubca4\ud2b8 \ub3d9\uc791\uc744 \uc27d\uac8c \ubcc0\uacbd\ud560 \uc218 \uc788\uac8c \ub418\uc5c8\ub2e4. \ub124\ube44\uac8c\uc774\uc158 \uacc4\uce35 \uad6c\uc870\uc758 \ucd5c\uc0c1\uc704 \ub808\ubca8\uc5d0\uc11c navController\ub97c \uc720\uc9c0\ud55c\ucc44\ub85c OverviewBody\uc5d0 \uc9c1\uc811 \uc804\ub2ec\ud558\uc9c0 \uc54a\uc73c\uba74, \uc774\ub7ec\ud55c \uc791\uc5c5\uc744 \uc218\ud589\ud560 \ub54c \uae30\uc874 navController\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0\ub3c4 OverviewBody\ub97c \ubd84\ub9ac\ud558\uc5ec \ubbf8\ub9ac\ubcf4\uae30\ud558\uac70\ub098 \ud14c\uc2a4\ud2b8\ud558\uae30 \uc27d\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Rally\ub294 \ucd08\uae30\uc5d0 Navigation\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uae30\uc874 \uc571\uc774\ub2e4. \ub124\ube44\uac8c\uc774\uc158\uc73c\ub85c \ub9c8\uc774\uadf8\ub808\uc774\uc158\ud558\ub294 \uba87 \uac00\uc9c0 \ub2e8\uacc4\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \ub124\ube44\uac8c\uc774\uc158 \uc758\uc874\uc131 \ucd94\uac00 NavController \ubc0f NavHost \uc124\uc815\ud558\uae30 \ubaa9\uc801\uc9c0 \ub8e8\ud2b8 \uc900\ube44\ud558\uae30 \uae30\uc874 \ubaa9\uc801\uc9c0 \uba54\ucee4\ub2c8\uc998\uc744 \ub124\ube44\uac8c\uc774\uc158 \ub8e8\ud2b8\ub85c \ubcc0\uacbd\ud558\uae30 \ub124\ube44\uac8c\uc774\uc158 \uc758\uc874\uc131 \ucd94\uac00\ud558\uae30 app\/build.gradle \ucc3e\uc544\uc11c \uc5f4\uc790. dependencies \ubd80\ubd84\uc5d0 navigation-compose \uc758\uc874\uc131\uc744 \ucd94\uac00\ud558\uc790. \ucd5c\uc2e0\ubc84\uc804\uc740 \uacf5\uc2dd\ubb38\uc11c\ub97c \ucc38\uc870\ud558\uc790 dependencies { implementation &#8220;androidx.navigation:navigation-compose:2.4.0-beta04&#8221; &#8230; } [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[38],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45742"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=45742"}],"version-history":[{"count":1,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45742\/revisions"}],"predecessor-version":[{"id":45743,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45742\/revisions\/45743"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=45742"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=45742"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=45742"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}