약간의 논란(?)은 있겠지만 이런 식의 코드가 코틀린과 자바에 모두에서 원활하게 돌아간다.
view.findNavController() 방식은 코틀린에서만 작동한다. 출처는 여기
A를 누르면 B가 나오고 하는 식으로 순서대로 A B C D 가 나오게 하면 된다.
코딩이 귀찮으니 코드를 다운받아서 확인해보자
D까지 올바르게 나오는지 확인해보자.
백 스택 관리
사실상 핵심 파트이다. 백 스택 관리를 원활하게 하려고 하는게 가장 큰 목적이다. 이 글은 독자가 스택 자료구조를 안다는 가정하에 쓰여졌다. popUp 속성들을 이용해서 백 버튼을 눌렀을 때 어떻게 동작할 지를 설정할 수 있다.
D에서 백 버튼을 누르면 C로 돌아갈 것이다. 당연하다고 생각할 수도 있겠지만, 이건 액션이 일어날 때 안드로이드에서 백 스택을 자동으로 생성해주었기 때문이다.
마찬가지로 C에서는 B로, B에서는 A로, 마지막 A에서는 앱이 종료되는 것을 알 수 있다.
만약에 D버튼을 눌렀을 때 A로 돌아가고 싶으면 어떻게 할까?
C-D
C에서 D로 가는 액션을 클릭한 그림이다.
오른쪽 Attributes 탭에서 Pop Behavior 속성을 확인할 수 있다. 현재 none으로 되어있는 것을 알 수 있다.
이걸 blankFragment(즉, A)로 바꾸고 앱을 실행해보자.
D에서 백 버튼을 누르면 A로 돌아가고 다시 한번 백 버튼을 누르면 앱이 종료되게 된다.
이번에는 Inclusive 옵션을 체크한 뒤에 다시 앱을 실행해보자.
D에서 백 버튼을 누르면 앱이 종료되는 것을 확인할 수 있다.
기본 원칙은 아래 4가지 이다.
액션의 popUpTo 속성은 주어진 도착점이 나올 때까지 백 스택을 팝업한다.
popUpToInclusive 속성이 false이거나 설정되지 않은 경우, popUpTo 는 지정된 도착점까지 모든 도착점들을 제거한다. 하지만 지정된 목적지는 백 스택에 들어있다.
popUpToInclusive 속성이 true인 경우, popUpTo 속성은 주어진 목적지를 포함해서 모든 목적지들을 백 스택에서 제거한다.
popUpToInclusive 속성이 true이고 popUpTo가 앱의 시작점으로 설정된 경우, action은 백 스택의 모든 도착점을 제거한다. 백 버튼을 누르면 바로 앱을 종료한다.
이렇게 글로만 보면 이해가 안되기 때문에 실험을 해보자.
약간의 실험들
복잡한 네비게이션 그래프
좀 더 복잡한 백스택을 만들기 위해서 네비게이션 그래프를 위와 같은 형태로 바꿔보자. (물론 액션을 이벤트에 연결해주어야 한다.)
A -> B, C B -> C, D C -> D D -> A 이런 액션이 있는 그래프이다.
상황 1
A -> B -> D -> A -> C -> D
C->D 액션에 popUpTo를 BlankFragment2로 지정하고 D에서 백 버튼을 누르면 어떻게 될까?
상황 2
A -> C -> D -> A -> C -> D
백 스택이 있기 때문에 C에서 백 버튼을 누르면 A로 돌아간다. C가 B에서 왔는지 A에 왔는지를 백 스택으로 확인할 수 있다.
C->D 액션에 popUpTo를 BlankFragment2로 지정하고 D에서 백 버튼을 누르면 어떻게 될까?
상황 3
A -> B -> D -> A -> B -> D
B -> D 액션에 popUpTo를 BlankFragment로 지정하고 마지막 D에서 백 버튼을 누르면 어떻게 될까?
상황 4
A -> B -> D -> A -> B -> D
B -> D 액션에 popUpTo를 BlankFragment로 지정하고 popUpToInclusive를 true로 한 상태에서, 마지막 D에서 백 버튼을 누르면 어떻게 될까?
해답
상황 1의 경우
B로 돌아간다. (A -> B) 이 상태에서 두 번 백 버튼을 누르면 종료된다.
상황 2의 경우
백 스택에 BlankFragment2가 들어있지 않기 때문에 그냥 popUpTo 옵션이 지정되어 있지 않은 상황과 같이 동작한다. 바로 전 C로 돌아간다.
상황 3의 경우
화면은 A로 바뀐다. 이 A는 A -> B -> D -> A 의 마지막 A이다. 여기서 백 버튼을 누르면 D로 돌아가고, (A -> B -> D) 또 백 버튼을 누르면 B가 아니라 A로 돌아가는데 이것은 B -> D 액션의 popUpTo가 BlankFragment로 지정되어 있기 때문이다. 또 백 버튼을 누르면 종료된다.
상황 4의 경우
원칙 4에 의해서 백 스택에 모든 도착점들이 사라진다. 화면은 그대로 D를 나타내고 있고, 이 상태에서 백 버튼을 누르면 앱이 종료된다.