Fragment화면간의 이동 및 흐름을 정의하기 위해 사용하는 구성요소이다.
Navigation graph를 사용하기 위해서는 크게 3가지가 필요하다.
애플리케이션의 모든 네비게이션 관련 정보가 들어있는 XML리소스.
사용자가 앱 내에서 이동할수 있는 모든 Flow를 보여주며, 앱 내의 모든 Fragment를 한번에 확인할 수 있다.
앱에서 네비게이션 대상이 표시되는 빈 컨테이너로 사용자가 앱 사용중 화면을 전환할때 NavHost에 프래그먼트들이 교체되며 전환된다.
보통 FrameLayout이나 FragmentContainerView를 통해 구현되지만, 구글에서는 FragmentContanerView를 사용하길 권장하고 있다.
사용자가 화면을 전환할때 화면간의 이동과 네게이션 흐름을 관리해주는 역할을 해주는 객체이다.
Navigation graph는 우선 Navigation graph xml파일을 설정해준 뒤, Fragment가 표시될 화면에 NavHost를 정의하고 소스코드에서 NavController를 연결해서 사용한다.
리소스 디렉토리 하위에 navigation디렉토리를 생성해준뒤, 원하는 이름으로 Navigation graph리소스 파일을 생성해준다.

<?xml version="1.0" encoding="utf-8"?>
<navigation
...
android:id="@+id/navi_graph"
app:startDestination="@id/main">
<!-- startDestination에 시작시 나올 Fragment의 Id를 넣어줘야한다. -->
<fragment
android:id="@+id/main"
android:name="com.android.intensiveproject.fragment.MainFragment"
android:label="main_fragment"
tools:layout="@layout/fragment_main" />
<!-- name에는 사용할 fragment의 경로를 넣어준다. -->
...
</navigation>
Nav graph에 사용할 Fragment들을 모두 정의해 준다.
만약 Bottom Navigation Menu와 연동하려면 menu파일에 있는 각 메뉴의 id값과
Nav graph내에 있는 Fragment중 해당 메뉴를 눌렀을때 실행될 Fragment의 id가 같아야한다.
만약 두 id가 일치한다면 Bottom Navigation Bar의 메뉴와 해당 Fragment는 자동으로 연동되어 메뉴 클릭시 해당 Fragment로 이동이 가능하다.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/main"
android:enabled="true"
android:icon="@drawable/btn_search_active"
android:title="이미지 검색"
app:showAsAction="always" />
<item
android:id="@+id/my_storage"
android:enabled="true"
android:icon="@drawable/btn_my_active"
android:title="내 보관함"
app:showAsAction="always" />
</menu>
<?xml version="1.0" encoding="utf-8"?>
<navigation ... >
<fragment
android:id="@+id/main"
android:name="com.android.intensiveproject.fragment.MainFragment"
android:label="main_fragment"
tools:layout="@layout/fragment_main"/>
<fragment
android:id="@+id/search"
android:name="com.android.intensiveproject.fragment.SearchFragment"
android:label="search_fragment"
tools:layout="@layout/fragment_search" />
</navigation>
Fragment를 표시할 Activity에 Nav Host를 생성해준다.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment" <-- NavHost받아옴
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true" <-- 기본 NavHost로 지정
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navi_graph" <-- NavGraph 연결
tools:layout="@layout/fragment_main" />
리소스 파일이 준비가 끝나면 Fragment가 보여질 Activity의 소스코드에서 Nav Host에 Nav Controller를 연결해준다.
val navHost = supportFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment
binding.bottomNavi.setupWithNavController(navHost.navController)
연결을 위해서는 현재 생성된 Fragment에 연동된 컨트롤러가 필요하기때문에 supportFragmentManager의 findFragmentByID를 사용해 생성되는 Nav host를 찾아온다.
Bottom Navigation에 setupWithNavController를 사용해 Nav Host의 navController를 연결해준다.
Fragment간 이동을 위해서는 우선 Nav graph에서 Action을 생성해 줘야한다.

Nav graph의 디자인 탭에서 프래그먼트의 오른쪽에있는 점을 드래그하면 위와같이 화살표가 연결되는데, 이때 코드쪽으로 돌아오면 자동적으로 Action이 생성되어있는걸 확인할 수 있다.
해당 Action은 소스코드에서 이동을 하기위해 사용할 수 있다.
binding.button.setOnClickListener{
findNavController().navigate(R.id.action_main_to_search)
}
위와 같이 findNavController를 통해 현재 사용되고있는 Nav Controller를 찾고, 이후 navigate메서드를 통해 실행시킬 Action의 id를 입력해주면 해당 Action이 실행되며 화면이 전환된다.

진짜 이러다 죽을 수도 있지 않을까...?
진짜 적당히 해야할거같다.