본문 바로가기

Android

[Android] Navigation Backstack Controll and Pass Data

Positano in Italy, Pictured by sson peace

Navigation을 이용하면 어떻게 fragment에서 결과값을 받아올 수 있을까?

NavBackStackEntry와 LiveData를 활용하면 fragment의 결과값 전달을 할 수 있다.

 

NavBackStackEntry

- 말 그대로 NavController의 BackStack으로 집입시켜주는 메서드이다.

- 이를 통해서 SavedStateHandle에 접근할 수 있다.

- SavedStateHandle은 viewModel의 상태를 저장해놓은 Saved State를 다루기 위한 객체이다.

 

그렇다면 navigation에는 backstack을 관리하기 위한 옵션들에 대해서 간단히 짚고 넘어가자

 

popUpTo는 주어진 도착점이 나올때까지 백스택을 팝업한다.

 

popUpToInclusive 속성이

1) false이거나 설정되지 않은 경우 지정된 도착점까지 모든 도착점들을 제거한다. 하지만 지정된 목적지는 백스택에 포함되어있다.

2) true인 경우 popUpTo 속성은 주어진 목적지를 포함해서 모든 목적지들을 팝업한다.

3) true이고 popUpTo가 시작점인 경우 모든 도착점을 제거한다. 백버튼 클릭시 앱 종료.

 

 

 

아래의 샘플코드는 최초 LogInFragment에서 SignUpFragment로 navigation의 action을 통해 넘어온 상태이다.

그러므로 BackStack에는 LogInFragment만 쌓여있다.

previousBackStackEntry를 이용하면 바로 이전 back stack으로 이동할 수 있다.

findNavController().previousBackStackEntry?.savedStateHandle?.set("id", id)
findNavController().previousBackStackEntry?.savedStateHandle?.set("password", password)
Navigation.findNavController(binding.root).popBackStack()

 

직접 Back Stack에 쌓여있는 클래스를 명시해줄 수도 있다.

이 경우에는 위 코드처럼 getBackStackEntry를 이용하면 된다.

findNavController().getBackStackEntry(R.id.FragmentLogIn).savedStateHandle.set("id", id)

 

이제 값을 넘겨받는 클래스에서 어떻게 수신하는지 알아보자.

우선 currentBackStackEntry를 통해서 자기 자신의 스택에 접근하고 saveStateHandle에 저장되어 있는 LiveData를 observe하면 된다.

 

private fun getSafeArgs() {
    findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("id")
        ?.observe(viewLifecycleOwner) {
            viewModel.id.value = it
        }
    findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("password")
        ?.observe(viewLifecycleOwner){
            viewModel.password.value = it
        }
}