JetPack 직전 DialogFragment 값 받아오기 (BackStackEntry, SavedStateHandle) [Android
반응형

 

Fragment에서 직전 DialogFragment의 값 받아오기

JetPack Navigation을 사용하며 Fragment들을 navigate할 때, DialogFragment를 사용하며 값을 받아올 일이 있다.

이렇게 이동


과정 : 주문 과정 중 쿠폰 선택
문제 : DialogFragment(쿠폰 선택 화면)에서 선택한 쿠폰 값을 Dialog를 호출한 Fragment(주문 화면)으로 받아와야 함

  1. Safe Args나 Bundle을 사용해 값 이동 (Navigate로 화면 전환)
  2. 이 경우에는 결국 주문 화면을 재호출하기 때문에, 쿠폰 선택 이전에 입력되었던 값들이 모두 초기화되어 버린다.
  3. 따라서 DialogFragment를 종료하며 값을 전달해야 했다.
  4. ViewModel 사용
  5. Fragment와 DialogFragment의 관계가 부모-자식 관계가 아니라, LifecycleOwner를 Activity로 잡아야 했는데, 매 새 주문화면마다
  6. 초기화를 시켜줘야하는 부분이 귀찮았다... (관리가 귀찮았음)

정말 간단하게 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

 

조건부 탐색  |  Android 개발자  |  Android Developers

조건부 탐색 앱 탐색을 설계할 때는 조건부 로직에 따라 다른 대상과 대조하여 한 대상으로 이동하는 것이 좋습니다. 예를 들어 사용자는 사용자가 로그인해야 하는 대상의 딥 링크를 따라가거

developer.android.com

 

참고

착각하고 있었던 것은, DialogFragment도 Fragment이기 때문에 기존의 Fragment (Dialog를 호출한) 의 생명주기가 영향이 있는 줄 알았었다. (onPaused - onResume이 실행되어서, 호출한 Fragment에서 언제 DialogFragment가 종료하였는지 확인할 수 있으리라 생각했다...)
하지만 DialogFragment는 호출한 Fragment의 생명주기에는 전혀 영향을 주지 않는다는 것을 명심하자.
https://developer.android.com/guide/components/fragments.html

 

프래그먼트  |  Android 개발자  |  Android Developers

A Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section

developer.android.com



전문가가 아니라 정확하지 않은 지식이 담겨있을 수 있습니다.
언제든지 댓글로 의견을 남겨주세요!

반응형