Android

Android) Navigation을 사용해 startActivityForResult 구현하기

가짜 개발자 2021. 4. 21. 16:16


안드로이드에서 생성한 Activity로부터 결과를 받아서 호출한 Activity에서 사용하려면 

startActivityForResult() 메소드를 사용해야 합니다. 새로 호출된 Activity에서 setResult()를 통해 돌려줄 결과를 저장하고 finish()로 Activity를 종료합니다. 이후 그 결과는 호출했던 Activity의 onActivityResult() 메소드를 통해 전달되게 됩니다.

 

 

 

그럼 Navigation 라이브러리를 사용하는 경우 어떻게 결과를 받아올 수 있을까요?

 

예를들어 위와 같은 nav_graph가 있습니다. 

 

메인 화면(main_fragment)에서 프로필(profile_fragment) 화면으로 가기 위해서 로그인(login_fragment)을 통한 인증을 해야 이동할 수 있다고 가정한다면 로그인 화면으로부터 결과 값을 받아와야 합니다.

 

결과를 저장하고 받아오기 위해 Navigation ComponentBackStackEntry와 가벼운 데이터를 저장하는 savedStateHandle을 이용하여 확장 함수를 만들겠습니다. 

fun Fragment.getNavigationResult(key: String = "result") =
    findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>(key)

fun Fragment.setNavigationResult(result: String, key: String = "result") {
    findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}

setNavigationResult 함수를 보면  키와 값을 저장할 수 있는 인자들이 있습니다.

Back Stack은 자료구조 Stack처럼 LIFO로 동작하는데, 생성한 프래그먼트에서 previousBackStackEntry를 통해 Back Stack에 올라간 프래그먼트에 값을 저장합니다.

 

호출한 프래그먼트에서 getNavigationResult를 통해 다시 currentBackStackEntrysetNavigationResult을 사용해 저장한 키를 통해 결괏값을 불러오는 방법입니다. savedStatehandle에서 제공하는 getLiveData를 통해 라이브 데이터처럼 사용할 수 있습니다.

 

사용방법은 아래와 같습니다.

// 생성한 프래그먼트
button.setOnClickListener {
	setNavigationResult(getString(R.string.toast_leave_room_success))
}

// 호출한 프래그먼트
getNavigationResultLiveData<String>()?.observe(viewLifecycleOwner) { result ->
            // Do Something with result.
        }

 

 

Back Stack 참고

처음 앱을 시작하면서 Activity1이 실행되었고 Stack의 맨 위에 쌓였습니다.

그리고 Activity2가 실행되었을 때 Activity1 위로 Activity2가 Stack에 쌓이게 되었습니다.

다시 Activity3가 실행되면서 Activity3가 Stack에서 가장 맨 위에 쌓이게 되었습니다.

여기서 뒤로가기 버튼을 눌러 Activity3를 종료하게 되면 Activity3는 Pop되어 Stack에서 삭제되고 그 밑에 있는 Activity2가 실행되었습니다.

만약 여기서 뒤로가기 버튼을 눌러 Activity2를 종료하면 Activity1이 실행됩니다.


Preference

How to get a result from Navigation

반응형