#1 개요
#1-1 소프트코딩 개요
지금까지는 +버튼을 누르면, 현재 시각을 기준으로 (하드코딩된) 더미 영양소 데이터를 담은 DayMealView 레코드가 INSERT되었다. 이제는 View에서 사용자가 시각 및 영양 데이터를 소프트코딩하여 ViewModel로 전송할 수 있게 만들어본다.
#1-2 채팅 UI를 위한 '채팅' 입력 창
이전에 계획한 방향대로 화면을 구성한다. 채팅 UI이므로 영양 데이터를 INSERT하는 방식은 하단에 고정되어있을 '채팅바'를 통해서 이뤄질 것이다.
#1-3 기존 UI와의 충돌
문제는 이미 하단에 NavigationBar가 존재한다는 점이다. 하단 바가 2개나 있으면 보기에도 안 좋을 뿐더러, 무엇보다 사용자 입장에서 헷갈린다. 우선순위를 따지자면 하단에 더 존재할법한 오브젝트는 '채팅바'다. NavigationBar가 수행하던 기능은 아마 TopAppBar()로 옮길 것 같다. 이 결정은 추후에 변경될 수도 있다. 그 기준은 언제나 사용자 경험이다.
#1-4 Scaffold의 bottomBar 분기화
NutrientScreen을 표시하는 경우 BottomAppBar()를, 그 외의 경우에는 기존에 만들어두었던 NavigationBar()를 여전히 표시하게 나눌 것이다.
#2 코드
#2-1 currentBackStackEntryAsState()
공식 문서에서 Compose의 화면 전환(Navigation)과 bottomBar를 연결지으려면, "currentBackStackEntryAsState() 함수를 사용"하라고 한다 (참고: NavBackStackEntry). 위 공식 링크의 코드 스니펫에선 컴포저블 BottomNavigation()에서 currentBackStackEntryAsState()를 사용하고 있는데, 난 한 계층 위로 올라가 Scaffold에서 currentBackStackEntryAsState()를 사용할 것이다. 코드는 아래와 같다.
#2-2 Recomposition을 통한 bottomBar 동적 변경
// in MainActivity.kt
...
class MainActivity : ComponentActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
...
setContent {
NutricapturenewTheme {
// Navigation 관리의 주체
val navController = rememberNavController()
val navBackStackEntry = navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry.value?.destination?.route
...
Scaffold(
...
bottomBar = {
when(currentRoute) {
Destination.NutrientScreen.route -> BottomAppBar { Text("test") }
else -> MainNavigationBar(navController)
}
},
...
) { ... ->
...
}
}
}
}
@Composable
private fun MainNavigationBar(navController: NavHostController) {
...
}
}
...
핵심은 currentBackStackEntryAsState()다. 왜일까? 이름에도 나와있지만, currentBackStackEntryAsState()는 State를 반환하기 때문이다. State는 Recomposition을 유발한다. 따라서, State인 navBackStackEntry에서 파생된 변수인 currentRoute 또한 Recomposition을 위한 '감시 대상'이 된다. 이는 위 코드에 있는 when 분기문에서도 적용된다. 만약, currentRoute가 State와 연이 없는 변수였다면 내가 의도한 대로 분기문이 작동하지 않는다 (실제로 해본 결과, 분기문이 Activity의 생애주기에서 딱 한 번 실행되고 이후로는 실행되지 않는다).
#3 요약
Recomposition을 이용해, Destination에 따라 bottomBar가 동적 할당되게 만들었다.
#4 완성된 앱
#4-1 스크린샷
다음 게시글부터 "test" 부분에 채팅창을 구현한다.
#4-2 이 게시글 시점의 Commit
#4-3 본 프로젝트의 가장 최신 Commit
'App 개발 일지 > Nutri Capture' 카테고리의 다른 글
Nutri Capture 프론트엔드 - Dimens와 함께 ChatBar 만들기 (0) | 2024.12.31 |
---|---|
Nutri Capture 프론트엔드 - Typography (2) | 2024.12.28 |
Nutri Capture 백엔드 - 이진 탐색 적용 (1) | 2024.12.17 |
Nutri Capture 프론트엔드 - item 추가ㆍ제거 애니메이션 (0) | 2024.12.15 |
Nutri Capture 프론트엔드 - INSERT 및 DELETE 버튼 구현 (1) | 2024.11.28 |