Android(kotlin) - JetPack Compose - Navigation

ํ•˜๋™ํ˜ ยท2023๋…„ 8์›” 23์ผ
0

Android Jetpack Compose

๋ชฉ๋ก ๋ณด๊ธฐ
22/30
post-thumbnail

๐Ÿ’ก Navigation Compose๋Š” Compose ๋ฐฐํฌ ๋ฒ„์ „๊ณผ ๋™์ผํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋•Œ๋ฌธ์—, https://developer.android.com/jetpack/compose/navigation?hl=ko ์—์„œ Navigation ๋ฒ„์ „์„ ํ™•์ธํ•˜์‹œ๊ณ  ์„ค์ •์„ ์ง„ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„ค์ •

  • ๋ฒ„์ „ํ™•์ธ!
dependencies {
    val nav_version = "2.5.3"

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

โ–ช๏ธpopUpTo

// room1์œผ๋กœ ์ด๋™ํ•˜๊ธฐ ์ „ home์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ์Šคํƒ์„ ๋ชจ๋‘ ์ œ๊ฑฐ ํ›„ room1์œผ๋กœ ์ด๋™ 
navController.navigate("room1") {
    popUpTo("home") 
}
  • Home, Room1, Room2๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •

  • ์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ํ™ˆ์œผ๋กœ ์ด๋™์‹œ popUpTo๋ฅผ ์ง€์ •

  • popUpTo๋Š” Home โ†’ Room1์œผ๋กœ ์ด๋™ํ›„ Room1 โ†’ Room2๋กœ ์ด๋™ํ•˜๋ฉด Room1์€ ์‚ฌ๋ผ์ง
    (์ƒํƒœ Home โ†’ Room2)

  • ์ฆ‰, Home๊ณผ ์ด๋™ํ•˜๋ ค๋Š” ๊ณณ ์‚ฌ์ด๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

  • inclusive

    navController.navigate("Home") {
                            popUpTo("Home") {
                                inclusive = true
                            }
                        }
    • inclusive = ture๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Home๊นŒ์ง€ ์ œ๊ฑฐ๋ฅผ ํ•œ๋‹ค.
    • ex) ๋™์ž‘ ๋ฐฉ์‹
    1. ์ฒ˜์Œ Home โ†’ Room1 ์œผ๋กœ ์ด๋™์‹œ Home์ด ์ œ๊ฑฐ๋œ๋‹ค. (์ƒํƒœ : Room1)
    2. Room1 โ†’ Room2๋กœ ์ด๋™์‹œ์—๋Š” popUpto๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค. (์ƒํƒœ Room1 โ†’ Room2)
    3. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ Home์œผ๋กœ ์ด๋™ํ•˜๋ฉด Room1 โ†’ Room2 โ†’ Home์œผ๋กœ ์•ž์— Home์ด ์—†์–ด ์•„๋ฌด๊ฒƒ๋„ ์ œ๊ฑฐ๋˜์ง€ ์•Š๋Š”๋‹ค.
    4. ์—ฌ๊ธฐ์„œ Room1์œผ๋กœ ์ด๋™ํ•˜๋ฉด Room1 โ†’ Room2 โ†’ Room1์œผ๋กœ Home์ด ์ œ๊ฑฐ๋œ๋‹ค.
๐Ÿ’ก `inclusive`๋Š” ์–ธ์ œ ์ฃผ๋กœ ์‚ฌ์šฉํ• ๊นŒ? ๋งŒ์•ฝ Home์—์„œ Login์ด ์„ฑ๊ณตํ•˜๋ฉด ๊ด‘๊ณ  ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ์ด๋•Œ Login์œผ๋กœ ์ด๋™์‹œ `inclusive๋ฅผ ์ ์šฉํ•œ popUpTo`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„ ๊ด‘๊ณ ํ™”๋ฉด์—์„œ ๋’ค๋กœ๊ฐ€๊ธฐ๋ฅผ ํ•˜๋ฉด Home ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•  ๊ฒƒ์ด๋‹ค.

โ–ช๏ธlaunchSingleTop

  • launchSingleTop: ์Šคํƒ ์ตœ์ƒ๋‹จ์— ์˜ฌ๋ผ๊ฐ€ ์žˆ์œผ๋ฉด, ์Šคํƒ์— ์Œ“์ง€ ์•Š์Œ
navController.navigate("Home") {
                        launchSingleTop = true
                    }
  • Home์—์„œ Home์œผ๋กœ ์ด๋™ํ•œ๋‹ค๊ณ  ๊ฐ€์ •
  • launchSingleTop์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด Home์—์„œ Home์œผ๋กœ ์ด๋™ํ•˜๋Š” ๋ฒ„ํŠผ์„ ํด๋ฆญ์‹œ ์Šคํƒ์— Home์ด ์—ฌ๋Ÿฌ๊ฐœ ์Œ“์ž„
  • launchSingleTop์„ ์‚ฌ์šฉํ•˜๋ฉด Home์„ ์—ฌ๋Ÿฌ๋ฒˆ ๋ˆŒ๋Ÿฌ๋„ ์ด๋ฏธ Home์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋”์ด์ƒ ์Œ“์ด์ง€ ์•Š์Œ

โ–ช๏ธ Argument Nav

  • ๋ฒ„ํŠผ ํด๋ฆฌ๊นƒ Argument/dong์„ ์ „๋‹ฌ
  • ํ•ด๋‹น composable์€ ์ „๋‹ฌ๋ฐ›์€ {userId}๋กœ ์ด๋™
@Composable
fun Navigation(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
) {
    // NavHost ์ƒ์„ฑ
    // ์ปจํŠธ๋กค๋Ÿฌ, ๋ชฉ์ ์ง€, modifier
    NavHost(navController, "Home", modifier = modifier) {
        // ๋ผ์šฐํ„ฐ ์„ค์ •
        composable("Home") {
            Column {
                // argument nav
                Button(onClick = {
                    navController.navigate("Argument/dong") {
                        launchSingleTop = true
                    }
                }) {
                    Text("userId ์ž…๋ ฅ๊ฐ’ ์œผ๋กœ ์—ฐ๊ฒฐ ์ด๋™")
                }
            }
        }

        composable("Argument/{userId}") {
            val userId = it.arguments?.get("userId")
            Text(text = "userId: $userId")
        }
    }
}

์ „์ฒด ์ฝ”๋“œ

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.compose_example.ui.theme.Compose_exampleTheme

class NavActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Compose_exampleTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background,
                ) {
                    Navigation()
//                    Greeting("Android")
                }
            }
        }
    }
}

/**
 * Navigation ์ด๋™์€ stack์ด ์Œ“์ธ๋‹ค.
 */
@Composable
fun Navigation(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
) {
    // NavHost ์ƒ์„ฑ
    // ์ปจํŠธ๋กค๋Ÿฌ, ๋ชฉ์ ์ง€, modifier
    NavHost(navController, "Home", modifier = modifier) {
        // ๋ผ์šฐํ„ฐ ์„ค์ •
        composable("Home") {
            Column {
                Text(text = "Home")
                Button(onClick = {
                    navController.navigate("room1")
                }) {
                    Text("room1 ์ด๋™")
                }
                Button(onClick = {
                    navController.navigate("room2")
                }) {
                    Text("room2 ์ด๋™")
                }
                Button(onClick = {
                    navController.navigate("Home") {
                        launchSingleTop = true
                    }
                }) {
                    Text("Home์œผ๋กœ ์ด๋™")
                }

                // argument nav
                Button(onClick = {
                    navController.navigate("Argument/dong") {
                        launchSingleTop = true
                    }
                }) {
                    Text("userId ์ž…๋ ฅ๊ฐ’ ์œผ๋กœ ์—ฐ๊ฒฐ ์ด๋™")
                }
            }
        }

        composable("room1") {
            Column {
                Text(text = "room1")
                Button(onClick = {
                    navController.navigate("Home")
                }) {
                    Text("Home์œผ๋กœ ์ด๋™")
                }
                Button(onClick = {
                    navController.navigate("room2")
                }) {
                    Text("room2 ์ด๋™")
                }
            }
        }

        composable("room2") {
            Column {
                Text(text = "room2")
                Button(onClick = {
                    navController.navigate("Home")
                }) {
                    Text("Home์œผ๋กœ ์ด๋™")
                }
                Button(onClick = {
                    navController.navigate("room1")
                }) {
                    Text("room1 ์ด๋™")
                }
            }
        }

        composable("Argument/{userId}") {
            val userId = it.arguments?.get("userId")
            Text(text = "userId: $userId")
        }
    }
}

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