Compose drawer menu - NavigationDrawer

Navigation Drawer

Navigation Drawer란 Drawer(=서랍)처럼 열고 닫는 식으로 동작하는 네비게이션 메뉴이다.

보통 애플리케이션 왼쪽 최상단 위치하여, TopAppBar에서 열고 닫을 수 있는 메뉴로서 사용된다.

그림1. topAppBar menu

닫힌 상태에서는 전혀 공간을 차지하기 않기 때문에 네비게이션 메뉴로 유용하게 사용할 수 있다.



ModalNavigationDrawer

Compose에서 navigation drawer 구현하기 위해서 ModalNavigationDrawer를 사용할 수 있다.


ModalNavigationDrawer를 알아보기 전에 우선 사용되는 변수들을 살펴보면

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
val icons = listOf(Icons.Filled.Home, Icons.Filled.Person, Icons.Filled.Settings)
val sample = listOf("Home", "Profile", "Setting")
var text by remember { mutableStateOf("") }

  • drawerState : drawer 상태 변수. opne, close 같은 drawer의 대한 상태 값을 갖는다.
  • scope : navigation을 open 하거나 close 할 때 사용할 코루틴 scope
  • icons : navigation 메뉴 아이콘
  • sample : navigation 메뉴 텍스트
  • text : 메뉴서 선택한 텍스트

여기서 drawerState 변수를 사용하여 navigation을 열고 닫는 동작을 제어한다.



계속해서 ModalNavigationDrawer 사용하는 방법을 알아보자


ModalNavigationDrawer의 구조를 살펴 보면 

drawer의 상태 값을 나타내는 1.drawerState

navigation drawer에서 보여줄 콘텐츠인 2.drawerContent

마지막으로 화면에 나타낼 3.content로 구성된다.

ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet {
Text(
text = "Menu",
modifier = Modifier
.
fillMaxWidth()
.
background(Color(253, 230, 149, 255))
.
padding(12.dp),
style = MaterialTheme.typography.headlineMedium
)
sample.
forEachIndexed { index, s ->
ListItem(modifier = Modifier.clickable {
text = s
scope.
launch {
drawerState.close()
}
},
headlineContent = { Text(s) },
leadingContent = {
Icon(
imageVector = icons[index],
contentDescription = ""
)
})
}
}
},
)
{
<메인 화면> (ex. Scaffold)

}

그러면 여기서 1, 2번 같은 경우에는 알겠는데, 3번이 어느 부분인지 명확하지 않을 수 있는데

3번은 Scaffold, Surface 같은 전체 레이아웃 대한 부분이다.


즉, ModalNavigationDrawer가 가장 바깥쪽에 위치해

다른 레이아웃을 다 구성한 후 마지막의 ModalNavigationDrawer로 감싸주면 된다.


이러한 구조 덕에 레이아웃을 좌우로 드래그 하여 navigation을 열고 닫을 수도 있다.


그림2. 실행 화면


추가적으로 3번 content 부분을 살펴보면 topBar menu 아이콘을 클릭할 때 drawerState 상태에 따라서 open, close 되도록 한다.

Scaffold(
topBar = {
TopAppBar(title = { Text("Nav Drawer") },
navigationIcon = {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = "menu",
modifier = Modifier
.padding(12.dp)
.clickable {
scope.launch {
drawerState.apply {
if (isClosed) open() else close()
}
}
}
)
}
)
}
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
.fillMaxSize()
.background(Color(255, 202, 167, 255)),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text, fontSize = 32.sp)
}
}



참고

전체 코드 | Github



댓글

이 블로그의 인기 게시물

Compose 스크롤 시 AppBar 처리 - TopAppBarScrollBehavior

Compose status bar transparent - 상태 바 색 변경

Compose Toast message - 토스트 메시지 사용