Fragment에서 직전 DialogFragment의 값 받아오기
JetPack Navigation을 사용하며 Fragment들을 navigate할 때, DialogFragment를 사용하며 값을 받아올 일이 있다.
과정 : 주문 과정 중 쿠폰 선택
문제 : DialogFragment(쿠폰 선택 화면)에서 선택한 쿠폰 값을 Dialog를 호출한 Fragment(주문 화면)으로 받아와야 함
- Safe Args나 Bundle을 사용해 값 이동 (Navigate로 화면 전환)
- 이 경우에는 결국 주문 화면을 재호출하기 때문에, 쿠폰 선택 이전에 입력되었던 값들이 모두 초기화되어 버린다.
- 따라서 DialogFragment를 종료하며 값을 전달해야 했다.
- ViewModel 사용
- Fragment와 DialogFragment의 관계가 부모-자식 관계가 아니라, LifecycleOwner를 Activity로 잡아야 했는데, 매 새 주문화면마다
- 초기화를 시켜줘야하는 부분이 귀찮았다... (관리가 귀찮았음)
정말 간단하게 DialogFramgent에서 선택한 값 하나를 딱 직전 Fragment로만 이동시키고 싶었는데, 검색해보니
BackStackEntry를 활용한 방법이 있었다.
BackStackEntry 활용
NavController.getPreviousBackStackEntry()
를 사용하면 직전의 NavBackStackEntry를 검색할 수 있다.
여기서 SavedStateHandle
을 사용하여 상태를 변경할 수 있는데, 여기다 값을 넣어주는 것이다.
값은 Map처럼 키-값 구조로 넣고, 키를 활용해 빼서 쓸 수 있다.
DialogFragment에서 보통 직전의 BackStack은 호출한 Fragment일테니, 여기다가 값을 넣고, 받는 Fragment에서는 NavController.getCurrentBackStackEntry()
를 사용하여 현재(본인)한테서 값을 빼다 쓰면 된다.
SavedStateHandle에 넣을 수 있는 타입은 지정되어 있는데, 만약 클래스를 넣고 싶으면 Parcelable
을 구현시키면 된다.
값 넣기(DialogFragment)
/***쿠폰 검색 화면 (PurchaseCouponDialogFragment) ***/
NavHostFragment.findNavController(PurchaseCouponDialogFragment.this)
.getPreviousBackStackEntry()
.getSavedStateHandle().set("couponParcel", couponModel);
값 빼서 쓰기(Fragment)
이때, 호출하는 프래그먼트에선 observe를 활용해서 값이 변동되면 바로바로 원하는 액션을 취해주도록 하자.
/***주문 화면 (PurchaseFragment) ***/
NavHostFragment.findNavController(PurchaseFragment.this)
.getCurrentBackStackEntry()
.getSavedStateHandle().getLiveData("couponParcel")
.observe(getViewLifecycleOwner(), new Observer<Object>() {
@Override
public void onChanged(Object o) {
purchaseViewModel.getUseCoupon().setValue((CouponModel) o);
}
});
로그인 - 프로필확인 상황의 예제를 친절하게 담은 공식 문서도 확인해보자.
https://developer.android.com/guide/navigation/navigation-conditional?hl=ko
참고
착각하고 있었던 것은, DialogFragment도 Fragment이기 때문에 기존의 Fragment (Dialog를 호출한) 의 생명주기가 영향이 있는 줄 알았었다. (onPaused - onResume이 실행되어서, 호출한 Fragment에서 언제 DialogFragment가 종료하였는지 확인할 수 있으리라 생각했다...)
하지만 DialogFragment는 호출한 Fragment의 생명주기에는 전혀 영향을 주지 않는다는 것을 명심하자.
https://developer.android.com/guide/components/fragments.html
전문가가 아니라 정확하지 않은 지식이 담겨있을 수 있습니다.
언제든지 댓글로 의견을 남겨주세요!
'코딩 > 안드로이드' 카테고리의 다른 글
안드로이드 이메일, 비밀번호 입력 폼 (머테리얼 디자인) [Android, JAVA] (1) | 2022.03.12 |
---|---|
안드로이드 트리 구조 리사이클러뷰 구현 (접었다 폈다) [Android, JAVA] (2) | 2022.02.19 |
안드로이드 Daum 주소 검색 API 활용하기 [Android] (6) | 2022.02.18 |
RecyclerView 아이템 클릭 이벤트 구현 [Android, JAVA] (4) | 2022.01.29 |
React-Native Network Request Failed Error [Android] (0) | 2021.02.16 |
Comment