강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

최병채님의 프로필 이미지
최병채

작성한 질문수

냉동코더의 알기 쉬운 Modern Android Development 입문

Practice4A-Navigation으로 UI의 화면전환 구현하기 (BottomNavigationView, AppBar)

navigation 화면 전환 질문드립니다.

작성

·

745

2

안녕하세요, 우선 질좋은 강의 해주셔서 감사드립니다.

다름이 아니라 Search Book 프래그먼트에서 검색어 입력 후 책을 클릭하면 Book Fragment로 이동합니다. 이 상태로 바텀 내비게이션의 Favorite Books 아이콘을 클릭하고 다시 Search Books 아이콘을 클릭하면 바텀 내비게이션 아이콘은 Favorite Books를 클릭한 상태로 보여집니다. 또한 Search Book Fragment를 보여줘야 할 것 같은데 여전히 클릭한 Book Fragment를 보여주고 있습니다.

어떻게 해결해야 할까요?

정리하자면, Book Fragment에 들어간 상태에서 BottomNavigationView의 Favorite Books 아이콘 클릭 후 다시 Search Books 아이콘을 클릭하면 이상하게 동작합니다. Search Books Fragment가 실행되게 하고 싶습니다.

답변 2

2

냉동코더님의 프로필 이미지
냉동코더
지식공유자

Jetpack Navigation으로 Bottom Navigation을 제어할 때 setupWithNavController를 사용했는데요, 공식 홈페이지 https://developer.android.com/guide/navigation/navigation-ui#bottom_navigation 의 설명에 따르면 setupWithNavController는 메뉴 사이를 이동할 때 각 상태를 backstack https://medium.com/androiddevelopers/multiple-back-stacks-b714d974f134 이라는 곳에 저장하고 다시 복원하는 동작을 하게 되어 있습니다.

그러니까 SearchFragment에서 BookFragment를 띄운 상태에서 다른 프래그먼트로 갔다가 다시 SearchFragment로 돌아왔을 때 SearchFragment가 아닌 BookFragment가 뜨는 것은 Jetpack Navigation의 정상적인 동작인 것입니다. 아이콘이 전환되지 않는 것은 BookFragment에 메뉴가 지정되어 있지 않기 때문에 전환되지 않는 것으로 보여지구요.

최병채 님은 Navigation의 기본적인 동작이 아닌 동작을 하길 원하시는 것이기 때문에 동작을 추가로 커스텀하셔야 합니다. 핵심은 프래그먼트를 전환할 때 위에 쌓인 다른 프래그먼트를 한번에 제거하는 것인데, Navigation의 스펙 https://developer.android.com/codelabs/basic-android-kotlin-training-navigation-backstack#3 상 action 기능으로 프래그먼트를 전환할 때 app:popUpTo와 popUpToInclusive 속성을 이용하면 위에 쌓여있는 프래그먼트를 제거할 수 있습니다.

이걸 Bottom Navigation에 적용하기 위해서는 코드를 다음과 같이 변경하시면 됩니다. setOnItemSelectedListener 내부에서 onNavDestinationSelected로 클릭된 메뉴아이템을 정확히 표시하도록 하고, popBackStack으로 클릭된 아이템을 스택에서 바로 끄집어 내 표시하도록 하는 것입니다.

- binding.bottomNavigationView.setupWithNavController(navController)
 
+ binding.bottomNavigationView.apply {
+     setupWithNavController(navController)
+     setOnItemSelectedListener { item ->
+         NavigationUI.onNavDestinationSelected(item, navController)
+         navController.popBackStack(item.itemId, inclusive = false)
+         true
+     }
}
최병채님의 프로필 이미지
최병채
질문자

감사합니다. 바로 해결되었습니다.

이렇게 원하는 문제를 해결 하는 방법을 찾을 수 있는 팁 같은게 있는지 여쭤보고 싶습니다.

저도 저 나름대로 찾아봤지만 못 찾아서 질문을 남긴거라서 되게 존경?스럽습니다.

공식문서를 정독해서 해당 기능을 빠삭하게 아는것이 최고의 방법일까요?

주말에도 불구하고 답변 남겨주셔서 감사합니다.

0

냉동코더님의 프로필 이미지
냉동코더
지식공유자

공식문서를 정독하는 것은 개인적으로는 그리 도움이 된다고 생각하지 않고 필요할 때 필요한 부분만 찾아보시면 될 것 같습니다.
중요한 것은 문제를 잘 분해해서 각각을 해결한 다음에 그걸 다시 조립하는 능력인데요, 그런 능력을 어떻게 배양해야할지? 에 대해서는 저도 잘 설명을 못 드리겠지만 어쨌든 더 많이 시도해보고 더 많이 찾아보는 것이 필요할 것 같습니다.

최병채님의 프로필 이미지
최병채

작성한 질문수

질문하기