박종훈 기술블로그

[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가 열리게 된다.

    이제 잘 동작할 것이다.