마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Drawer Navigation 화면 이동을 하고싶습니다.

0 추천

dropdownmenu

화면의 dropdownmenu 의 Setting을 누르면 drawer navigation 메뉴중 setting 으로 이동하는걸

원합니다.

 

 

- 파일 MainNavigation.kt -
enum class MainRoute(value: String) {
    Home("home"),
    Navigation("navigation"),
    Settings("settings")
}

private data class DrawerMenu(val icon: ImageVector, val title: String, val route: String)

private val menus = arrayOf(
    DrawerMenu(Icons.Filled.Home, "Home", MainRoute.Home.name),
    DrawerMenu(Icons.Filled.Settings, "Settings", MainRoute.Settings.name),
)

@Composable
private fun DrawerContent(
    menus: Array<DrawerMenu>,
    onMenuClick: (String) -> Unit
) {
    Column(
        modifier = Modifier.fillMaxSize()
    ) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
        ) {
        }
        menus.forEach {
            NavigationDrawerItem(
                label = { Text(text = it.title)},
                icon = { Icon(imageVector = it.icon, contentDescription = null)},
                selected = false,
                onClick = {
                    onMenuClick(it.route)
                }
            )
        }
    }
}

@Composable
fun MainNavigation(
    navController: NavHostController = rememberNavController(),
    coroutineScope: CoroutineScope = rememberCoroutineScope(),
    drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
) {
    ModalNavigationDrawer(
        drawerState = drawerState,
        drawerContent = {
            ModalDrawerSheet {
                DrawerContent(menus) { route ->
                    coroutineScope.launch {
                        drawerState.close()
                    }
                    navController.navigate(route)
                }
            }
        }
    ) {
        NavHost(navController = navController, startDestination = MainRoute.Home.name) {
            composable(MainRoute.Home.name) {
                HomeScreen(drawerState)
            }
            composable(MainRoute.Settings.name) {
                SettingsScreen(drawerState)
            }
        }
    }
}

- 파일 AppBar.kt -

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainAppBar(drawerState: DrawerState?, title: String) {
    val coroutineScope = rememberCoroutineScope()
    var expanded by remember { mutableStateOf(false)}

    CenterAlignedTopAppBar(
        navigationIcon = {
            if (drawerState != null) {
                IconButton(onClick = {
                    coroutineScope.launch {
                        drawerState.open()
                    }
                }) {
                    Icon(Icons.Filled.Menu, contentDescription = "")
                }
            }
        },
        title = { Text(text = title) },
        actions = {
            IconButton(
                onClick = { expanded = true }) {
                Icon(Icons.Filled.MoreVert, null)
            }
            DropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                DropdownMenuItem(
                    text = { Text("Setting") },
                    onClick = {  여기 }
                )
            }
        }
    )
}
 
onClick에서 뭘해줘야하나요? navcontroller를 넣으면 오류가나서리
ellrewa (260 포인트) 님이 4월 18일 질문
ellrewa님이 4월 18일 수정

1개의 답변

0 추천

질문으로 봐서는 Jetpack Compose를 사용하신지 얼마 되지 않아서. Jetpack Compose의 코드 구조가 어떻게 되어야 하는지 많이 낯설어 하시는 것 같네요. Jetpack Compose는 function 을 기초로하는 특성상

 state 는 위에서 아래로 (top-down)
event 는 아래에서 위로( bottom-up)

구조로 코드를 작성하게 됩니다.

따라서 MainAppBar내의 onClick 이벤트는 함수로 받아서 제일 윗단의 @Composable에 넘기고 최종 처리는 이벤트에 따라서 액티비티/프레그먼트 또는 ViewModel에서 처리하도록 구성하시는게 권장되는 구조입니다.

따라서 아래처럼 코드가 구성되는 것이 일반적입니다.

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainAppBar(
   drawerState: DrawerState?, 
   title: String,
   onDropDownMenuItemClicked: (String) -> Unit
) {
    ...
            }
            DropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                DropdownMenuItem(
                    text = { Text("Setting") },
                    // title보다는 메뉴의 키가 될 수있는 값을 MainAppBar에서 받을 수 있도록 하는게 더 낫습니다.
                    onClick = {  onDropDownMenuItemClicked(title) }
                )
            }
        }
    )
}

위왁 같이 람다를 파라미터로 받으시고 이 Composable을 호출하는쪽에서 다시 람다를 넘기게 하시고 최종적으로 NavController에 접근할 수 있는 액티비티 같은 곳에서 navController.navigate("...") 호출해서 처리하시면 됩니다.

spark (227,830 포인트) 님이 4월 18일 답변
spark님이 4월 18일 수정
...