[TIL] Android - Navigation Component 사용 중 DialogFragment 결과값 받기
NavigationComponent
[Android] Navigation Component 사용 중 DialogFragment 결과값 받기
Navigation Component의 backStack을 활용해서 데이터를 주고 받는게 가능하다.
예시로 ExamFragment에서 ExamDetailDialogFragment로 navigate
한 경우
백스택에 대한 정보를 ArrayDeque<NavBackStackEntry>
타입으로 ExamDetailDialogFragment, ExamFragment의 값을 가진다.(NavController.backQueue
를 통해 확인 가능)
이를 이용해 savedState에 접근해 값을 관찰하거나 값을 지정할 수 있다.
확장 함수를 이용하는 방법 - 코드
fun <T> Fragment.getNavigationResult(key: String) =
findNavController()
.currentBackStackEntry
?.savedStateHandle
?.apply { remove<T>(key) }
?.getLiveData<T>(key)
fun <T> Fragment.setNavigationResult(key: String, data: T) {
findNavController()
.previousBackStackEntry
?.savedStateHandle
?.set(key, data)
}
사용예시
class ExamFragment: Fragment() {
...
private fun showDialog() {
getNavigationResult<String>(ExamDetailDialogFragment.EXAM_KEY)
?.observe(viewLifecycleOwner) {test ->
...
}
val action = ...
findNavController().navigate(action)
}
}
class ExamDetailDialogFragment: DialogFragment() {
...
override fun onDismiss(dialog: DialogInterface) {
setNavigationResult(EXAM_KEY, "Test")
}
...
companion object {
const val EXAM_KEY: String = "exam_key"
}
}
주의사항
- popUpTo 및 popupToInclusive 를 이용한 경우 백스택이남지않아 crash가 날 수 있다.
- 확장함수에서 currentBackStackEntry, previousBackStackEntry로 savedStateHandle을 가져오다보니 해당 확장함수의 호출 시점을 잘 판단하고 사용해야한다.
- 현재 예시처럼
getNavigationResult
를navigate()
호출하기 전에 사용하면 잘 동작하지만 순서를 바꿔navigate()
후getNavigationResult
를 사용하는 경우 동작하지 않는다.
- 현재 예시처럼