Jetpack Navigation

Jetpack Navigation의 장점:

  • 직관적인 Navigation 관리: Navigation Graph를 통해 앱의 Navigation 구조를 시각적으로 파악하고 관리할 수 있습니다.
  • 유형 안전한 데이터 전달: Safe Args를 사용하여 Fragment 간에 데이터를 안전하게 전달할 수 있습니다.
  • 간편한 Fragment 이동: navigate()popBackStack() 메서드를 사용하여 Fragment 이동을 간편하게 처리할 수 있습니다.
  • deep link 지원: 앱 외부의 링크를 통해 특정 Fragment로 바로 이동할 수 있습니다.
  1. Action 검색:

    • NavController는 전달받은 action ID를 기반으로 Navigation Graph에서 해당 Action을 찾습니다.

    • Action에는 이동할 목적지 Fragment (Destination) 정보와 전달할 데이터(Arguments) 등이 포함되어 있습니다.

  2. Destination 확인:

    • Action에서 지정된 Destination Fragment의 유형을 확인합니다.

    • Fragment, Activity, DialogFragment, Custom Destination 등 다양한 유형의 Destination을 지원합니다.

  3. 현재 상태 저장 (선택 사항):

    • saveState() 메서드를 통해 현재 Fragment의 상태를 저장할 수 있습니다.

    • 이는 Fragment가 다시 표시될 때 이전 상태를 복원하기 위해 필요합니다.

  4. Argument 전달 (선택 사항):

    • Safe Args를 사용하여 Destination에 정의된 Argument를 전달할 수 있습니다.

    • Argument는 Bundle 형태로 전달되며, Destination Fragment에서 arguments 속성을 통해 받을 수 있습니다.

  5. FragmentTransaction 생성:

    • NavController는 FragmentManager를 사용하여 FragmentTransaction을 생성합니다.

    • FragmentTransaction은 Fragment 추가, 삭제, 교체 등 Fragment 상태 변경 작업을 정의합니다.

  6. FragmentTransaction 실행:

    • 생성된 FragmentTransaction을 실행하여 새로운 Destination Fragment를 화면에 표시합니다.

    • 이때, 사용자가 정의한 Transition 애니메이션이나 기본 애니메이션이 적용될 수 있습니다.

  7. Lifecycle Callback 호출:

    • Fragment 생명주기(onCreate, onViewCreated, onResume 등)에 따라 필요한 콜백 메서드가 호출됩니다.

    • 이를 통해 Fragment 초기화, 데이터 로드, UI 업데이트 등의 작업을 수행할 수 있습니다.

  8. BackStack 업데이트 (선택 사항):

    • navigate() 메서드에 addToBackStack 옵션을 true로 설정하면, 현재 Fragment가 BackStack에 추가됩니다.

    • 사용자가 뒤로 가기 버튼을 누르면 BackStack에 저장된 Fragment가 다시 표시됩니다.

추가 고려 사항:

  • ViewModel 공유: by activityViewModels() 또는 by navGraphViewModels()를 사용하여 ViewModel을 공유하고, Fragment 간에 데이터를 안전하게 전달할 수 있습니다.
  • Deep Link: navigate() 메서드에 URI를 전달하여 Deep Link를 통해 특정 Destination으로 이동할 수 있습니다.
  • Navigation Listener: NavController.OnDestinationChangedListener를 등록하여 Destination 변경 이벤트를 감지하고 추가 작업을 수행할 수 있습니다.

FragmentManager 를 통한 Transaction

image-20240519154407381.png

  • add: Host Activity의 생명주기에 Fragment 생명주기 추가, add된 Fragment는 onAttach ~ onResume까지 호출

    • Add a fragment to the activity state.
  • remove: onPause ~ onDetach까지 호출, Fragment가 메모리에서 제거됨.

    • Remove an existing fragment. If it was added to a container, its view is also removed from that container.
  • replace: replace() 함수 인자로 지정된 Fragment를 제외한 나머지 모든 프래그먼트가 remove

    • (나머지 Fragment는 onDetach 까지 호출, 지정된 Fragment는 onAttach ~ onResume )
  • show / hide: 기본적으로 add된 Fragment를 대상으로 View를 보이게 하거나 감춤.(visibility 변경)

  • attach: 대상 Fragment의 onCreateView ~ onResume 까지 호출

    • Re-attach a fragment after it had previously been detached from the UI with detach(android.app.Fragment). This causes its view hierarchy to be re-created, attached to the UI, and displayed.
  • detach: 대상 Fragment의 onPause ~ onDestroyView 까지 호출

    • Detach the given fragment from the UI. This is the same state as when it is put on the back stack: the fragment is removed from the UI
  • backStack 에서 없어지면(pop되면), onDestoryView ~ onDetach 까지 호출

  • backStack 에 존재하면, onDestoryView 까지만 호출, 다시 backStack 최상단에 특정 Fragment가 존재하면, onCreateView 부터 호출

  • A -> B로 naviagte() 시, B가 Create 되고, A가 Destory 됨. (선 Create, 후 Destory)

  • popUpTo 속성으로 특정 Fragment를 지정하면, 그 사이NavBackStackEntry 은 backStack에서 제거된다.
  • popUpToInclusive 속성을 true로 설정해주면, backStack popUpTo로 지정된 NavBackStackEntry 은 제거된다.
  • popUpToInclusive 값을 지정하지 않으면, popUpToInclusive=false와 같다.
    • false가 default