박종훈 기술블로그

[Jetpack Compose] Navigation Drawer와 TopAppBar 연결하기

자료가 많이 없어서 헤맸었기 때문에 이 부분도 정리해본다.

다 만들고 나서 정리를 하는 것이다 보니 중간중간에 갑자기 튀어나오는 부분이 있을 수 있다.

1. 일단 AppTopBar에 menu 버튼을 추가해보자.

modifier 관련된 부분들은
[Jetpack Compose] nestedScroll connection 을 이용하여 스크롤 시에 AppTopBar를 사라졌다 보였다 하게 하기
에서 작업된 부분이다.

Scaffold(
        modifier = Modifier.nestedScroll(nestedScrollConnection),
        topBar = {
            TopAppBar(
                title = { Text(stringResource(id = R.string.app_name)) },
                modifier = Modifier.offset {
                    IntOffset(
                        x = 0, y = topAppBarOffsetHeightPx.value.roundToInt()
                    )
                },
                navigationIcon = {
                    Icon(
                        Icons.Default.Menu,
                        stringResource(id = R.string.menu),
                        modifier = Modifier
                            .padding(16.dp, 16.dp)
                            .size(24.dp)
                            .clickable(
                                interactionSource = interactionSource,
                                indication = null,
                                onClick = {
                                    /* TODO */
                                }
                            )
                    )
                }
            )
        },
        containerColor = MaterialTheme.colorScheme.background,
        content = {
            /* content */
        }
    )

이렇게 하면 TopAppBar의 좌측에 아이콘이 생겼을 것이다.

2. Navigation Drawer를 추가하자 + TopAppBar와 연결 시키기

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)

    ModalNavigationDrawer(
        gesturesEnabled = !drawerState.isClosed,
        drawerState = drawerState,
        drawerContent = {
            ModalDrawerSheet(
                Modifier
                    .fillMaxHeight()
                    .width(300.dp)
            ) {
                NavigationDrawerItem(
                    /* DrawerItem*/
                )
            }
        }
    ) {
        /* Screen Content */
        ScreenContent(drawerState)
    }

drawerState는 Navigation Drawer 의 상태를 컨트롤 하기 위한 변수이다.

기존의 화면에 있던 것들을 ScreenContent 안으로 옮겨주면 된다.

gesturesEnabled = !drawerState.isClosed 이렇게 설정해준 이유는 gmail 앱을 참고하였는데
drawer가 닫혀 있을 때는 제스쳐는 사용 불가능하고 메뉴 아이콘을 누르면 메뉴가 열리게 하였고
drawer가 열려 있을 때는 제스쳐로 drawer를 닫을 수 있도록 해두었다.

ModalDrawerSheet 의 너비를 300dp 로 한 이유는 기본값으로 할 경우에 우측 여백이 너무 좁아서 였다. 원하는대로 수정하면 되겠다.

이후 navigation Icon의 onClick 에서

coroutineScope.launch {
    drawerState.open()
}

위와 같이 처리해주면 메뉴 아이콘을 눌렀을 때 drawer가 열리게 된다.

이제 잘 동작할 것이다.