마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Navigation 컴포넌트의 스택관련 질문드립니다

0 추천
현재 바텀내비게이션을 이용하고 있습니다.

메뉴화면에서 다른 메뉴로 전환이 아니라 해당 메뉴화면에서 버튼을 눌러 다른 화면으로

자꾸 이동하는 방식인 그런 기능을 만들고 있습니다.

모든 화면은 Fragment입니다. 다이얼로그도 DialogFragment입니다.

자세하게 적자면

메뉴화면(A) -> 화면 B(Dialog) 전환 -> 데이터 선택과 동시에 화면 C로 전달 및 전환

-> 화면 C (B에서 전달받은 데이터로 화면 타이틀 셋팅) -> C의 버튼 클릭

-> 화면 D 전환 -> D에서 데이터 선택 및 화면 C로 다시 전환

-> 화면 C에서 D에서 받은 데이터를 기반으로 아이템 추가

이정도인데.. 앱 기능상 C, D 부분에 계속 되기에 스택을 이용했습니다

nav_graph에 popUpTo라는 속성이 있더군요.

이게 대충 A->B->C->A 라는 화면 전환이 이루어진다고 할때

popUpTo를 사용하지 않으면 `C`에서 `A`로 갈때 계속 스택에 쌓이는 구조지만

popUpTo를 사용하면 C->A로 갈때  중간에 있는 C`와 `B를 스택에서 제거해서 반복하는 것 같더군요 [참고영상] https://www.youtube.com/watch?v=mLfWvSGG5c8

제거후 기존에 있던 A를 그대로 사용하는 것인줄 알았는데

실험을 해보니.. 이 기존의 스택 A는 유지한채 새로운 A를 만들어서 사용하는것 같더라구요..

저는 기존의 A를 유지하고 싶습니다.

그러니까 제 예제에서는 C를 유지하고 싶은거겠죠..현재로써는 D에서 C로 넘어오면

C에서 셋팅한 타이틀이 없습니다. 즉 새로만든 화면이라는 뜻이겠죠..

어떻게하면 기존 C화면을 계속 유지할 수 있나요?
codeslave (3,940 포인트) 님이 2021년 7월 4일 질문

1개의 답변

0 추천
말씀하신 것이 현재 Navigtion Component가 동작하는 방식이예요. replace를 기본적으로 사용하기 때문에 프레그먼트를 변경할 때마다 프레그먼트 안의 뷰를 destroy시켰다가 화면에 다시 돌아올 때 복구를 해줍니다. 백스택은 프레그먼트를 보관하는게 아니라 Fragment Transaction을 보관합니다.

따라서 시스템이 기본적으로 보관해주는 데이터도 있지만, 님이 다시 복구해줘야 하는 데이터도 생기게 됩니다.

이 방법을 해결할 수 있는 방법은 제가 아는 건 두가지입니다.
하나는 ViewModel의 LiveData 등을 사용해서 화면에서 복구되어야 할 데이터를 postValue나 value 등을 통해 업데이터 하는 방법입니다. LiveData는 화면이 Inactive되면 observer가 observing을 중단 했다가 다시 activve가 되면 자동으로 observer들에게  LiveData에 있는 데이터를 보냅니다. 따라서 LiveData의 구조를 잘 가져가면 뷰상태 복구가 자동으로 가능하구요.

두번째는 Multistack이라는 방법을 사용하는 겁니다. 이 방법은 Navigation Component에 커스텀 세팅이 필요합니다. Bottom Navigation 메뉴별로 별도의 Graph를 만들고 ChildFragment를 통해 개별적인 스택을 보관합니다. 현재 Navigation Component가 이 기능을 지원하기 위해 작업 중에 있습니다. Navigation Component Multistack이라고 검색해 보시면 원하시는 검색결과가 나올 겁니다. 이 방법을 원하시면 직접 구현을 하시거나 적당한 라이브러리를 찾아서 사용하시면 됩니다.

어떤 방법을 사용하더라도 어느정도의 추가적인 코드는 피할 수 없습니다. 둘다 테스트 해보시고 본인의 상황에 맞는 방법을 선택하시면 될 것 같습니다.
spark (227,470 포인트) 님이 2021년 7월 4일 답변
spark님이 2021년 7월 4일 수정
흠 선생님 답변에서는 ViewModel이나 LiveData를 사용해서 데이터를 유지시키는 방법을 사용해보시라고 했는데요,

선생님이 제시한 방법은 돌아온 화면을 그대로 사용할때 아닌가요?

그런데 제가 본문에서도 적어놨지만 A->B->C->A 라는 화면전환을 한다고 칠때,
popUpTo="A"를 하면 스택이 A A 상태가 됩니다.

맨처음의 A화면과 돌아왔을때 새로 켜진 A요..저는 기존의 맨처음 A로 돌아가고 싶은데 새로 켜진 A를 어떻게 할 순 없을까요?

아니면 popUpToInclusive 이라는 속성이 있던데 이건 아예 다삭제하고 처음부터
시작하는거라던데.. 이 속성을 사용해서 말씀하신 ViewModel과 LiveData를
사용해야할까요?
스택에 같은 프레그먼트가 한개만 쌓이는 걸 원하시면, 아래옵션이 도움이 될겁니다.
https://developer.android.com/reference/androidx/navigation/NavOptions#shouldLaunchSingleTop()
...