์ฌ์ฉ์๊ฐ ์ฑ ๋ด์์ ์๋ก ๋ค๋ฅธ ์ฝํ ์ธ ํ๋ฉด๋ค ์ฌ์ด๋ฅผ ์ด๋ํ๊ณ ํ์ํ ์ ์๊ฒ ํ๋ ์ํธ์์ฉ์ ๋ํ๋.
Navigation graph
๋ชจ๋ ๋ค๋น๊ฒ์ด์
๊ด๋ จ ์ ๋ณด๋ฅผ ํ ๊ณณ์ ์ง์ค์ํจ xml ๋ฆฌ์์ค. ์ฑ ๋ด ๊ฐ๊ฐ์ ๋ชฉ์ ์ง๋ฟ๋ง ์๋๋ผ ์ฌ์ฉ์๊ฐ ์ฑ์ ํตํด ์ด๋๊ฐ๋ฅํ ๊ฒฝ๋ก๋ ํฌํจ๋จ.
NavHost
๋ค๋น๊ฒ์ด์
๊ทธ๋ํ์์ ๋ชฉ์ ์ง๋ฅผ ํ์ํ๋ ๋น ์ปจํ
์ด๋. ๋ค๋น๊ฒ์ด์
์ปดํฌ๋ํธ์๋ fragment ๋ชฉ์ ์ง๋ฅผ ํ์ํ๋ ๊ธฐ๋ณธ NavHost๋ฅผ ๊ตฌํํ NavHostFragment๊ฐ ํฌํจ๋์ด ์์.
NavController
NavHost ๋ด์์ ์ฑ ๋ค๋น๊ฒ์ด์
์ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด. NavController๋ ์ฌ์ฉ์๊ฐ ์ฑ์ ํตํด ์ด๋ํ ๋ NavHost์์ ๋ชฉ์ ์ง ์ปจํ
์ธ ๋ฅผ ๊ต์ฒดํ๋ ์ญํ ์ ๋ด๋น.
์ฑ์ ํตํด ์ด๋ํ๋ ๋์ NavController์๊ฒ ๋ด๋น๊ฒ์ด์ ๊ทธ๋ํ์ ํน์ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ ์ด๋ํ๊ฑฐ๋ ํน์ ๋ชฉ์ ์ง๋ก ์ง์ ์ด๋ํ๊ณ ์ถ๋ค๊ณ ์๋ฆฌ๋ฉด NavController๋ NavHost์์ ์ ์ ํ ๋ชฉ์ ์ง๋ฅผ ํ์ํจ.
โญ ์ฐธ๊ณ
Android 13์์๋ Android ๊ธฐ๊ธฐ์ฉ Navigation ์ปดํฌ๋ํธ์ ํจ๊ป ์๋ํ๋ predictive back navigation์ด ๋ฐํ๋์์. ํฅํ ๋ฆด๋ฆฌ์ค์์ ์์์น ๋ชปํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ๊ฐ๋ฅํ ๋นจ๋ฆฌ predictive back navigation์ ๊ตฌํํ๋ ๊ฒ์ด ๊ถ์ฅ๋จ.
๋ค๋น๊ฒ์ด์ ์ ์ฌ์ฉ์๊ฐ ์ด๋ํ ์ ์๋ ์ฑ์ ๋ชฉ์ ์ง ์ฌ์ด์ ๋ฐ์ํจ. ๋ชฉ์ ์ง๋ ์ก์ ์ ํตํด ์ฐ๊ฒฐ๋์ด ์์.
Navigation graph๋ ๋ชจ๋ ๋ชฉ์ ์ง์ ์ก์ ์ ํฌํจํ๋ ๋ฆฌ์์ค ํ์ผ. ์ด ๊ทธ๋ํ๋ ์ฑ์ ๋ชจ๋ ๋ด๋น๊ฒ์ด์ ๊ฒฝ๋ก๋ฅผ ๋ํ๋.
์์ ๊ทธ๋ฆผ์์
1. ๋ชฉ์ ์ง๋ ์ฑ ๋ด์ ์๋ก ๋ค๋ฅธ ์ปจํ
์ธ ์์ญ์ ๋ํ๋.
2. ์ก์
์ ์ฌ์ฉ์๊ฐ ๋ฐ๋ฅผ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ๋ํ๋ด๋ ๋ชฉ์ ์ง ๊ฐ์ ๋
ผ๋ฆฌ์ ์ธ ์ฐ๊ฒฐ.
๐ก ๋ค๋น๊ฒ์ด์
๊ทธ๋ํ๋ฅผ ํ๋ก์ ํธ์ ์ถ๊ฐํ๊ธฐ ์ํ ๋จ๊ณ
1. ํ๋ก์ ํธ ์ฐฝ์์ res ๋๋ ํ ๋ฆฌ๋ฅผ ์ฐํด๋ฆญํ ํ New > Android Resource File์ ์ ํ.
2. File name ํ๋์ "nav_graph"์ ๊ฐ์ ์ด๋ฆ์ ์
๋ ฅ.
3. Resource type ๋๋กญ๋ค์ด ๋ชฉ๋ก์์ Navigation์ ์ ํํ ํ OK ํด๋ฆญ.
๋ค๋น๊ฒ์ด์ ์๋ํฐ์์ ์๊ฐ์ ์ผ๋ก ๋ด๋น๊ฒ์ด์ ๊ทธ๋ํ๋ฅผ ํธ์งํ๊ฑฐ๋ ๊ธฐ๋ณธ XML์ ํธ์ง.
์ ๊ทธ๋ฆผ์์
1. Destinations panel: ๋ด๋น๊ฒ์ด์
ํธ์คํธ ๋ฐ ํ์ฌ ๊ทธ๋ํ ์๋ํฐ์ ์๋ ๋ชฉ์ ์ง๋ฅผ ๋์ด.
2. Graph Editor: ๋ค๋น๊ฒ์ด์
๊ทธ๋ํ์ ์๊ฐ์ ํํ์ด ์๋ ๊ณณ.
3. Attributes: ๋ค๋น๊ฒ์ด์
๊ทธ๋ํ์์ ํ์ฌ ์ ํ๋ ํญ๋ชฉ์ ๋ํ ์์ฑ ํ์.
Text ํญ์ ํด๋ฆญํ๋ฉด XML์ด ๋ณด์.
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph">
</navigation>
<navigation>
element๋ ๋ด๋น๊ฒ์ด์
๊ทธ๋ํ์ root.
๋ชฉ์ ์ง ๋ฐ ์ก์
์ ์ถ๊ฐํ ๋์ element์ธ <destination>
๊ณผ <action>
์ด ์์ ์์๊ฐ ๋จ.
์ค์ฒฉ๋ ๊ทธ๋ํ๊ฐ ์๋ ๊ฒฝ์ฐ ํด๋น ๊ทธ๋ํ๋ ์์ <navigation>
์ด ๋จ.
๋ค๋น๊ฒ์ด์
ํธ์คํธ๋ ์ฌ์ฉ์๊ฐ ์ฑ์ ํตํด ์ด๋ํ๋ ๋์ ๋ชฉ์ ์ง๊ฐ ๊ต์ฒด๋๋ ๋น ์ปจํ
์ด๋.
๋ค๋น๊ฒ์ด์
ํธ์คํธ๋ NavHost์์ ํ์๋์ด์ผ ํจ. ๋ค๋น๊ฒ์ด์
์ปดํฌ๋ํธ์ ๊ธฐ๋ณธ NavHost ๊ตฌํ์ธ NavHostFragment๋ ํ๋๊ทธ๋จผํธ ๋ชฉ์ ์ง๋ฅผ ๊ต์ฒดํ๋ ์์
์ ์ฒ๋ฆฌํจ.
โญ๏ธ ๋ค๋น๊ฒ์ด์
์ปดํฌ๋ํธ๋ ์ฃผ๋ก ์ฌ๋ฌ ํ๋๊ทธ๋จผํธ ๋ชฉ์ ์ง๋ฅผ ๊ฐ์ง ํ๋์ ๋ฉ์ธ ์กํฐ๋นํฐ๋ฅผ ๊ฐ์ง ์ฑ์ ๋์์ผ๋ก ์ค๊ณ๋์์. ๋ฉ์ธ ์กํฐ๋นํฐ๋ ๋ด๋น๊ฒ์ด์
๊ทธ๋ํ์ ๊ด๋ จ์์ผ๋ฉฐ ํ์์ ๋ฐ๋ผ ๋ชฉ์ ์ง๋ฅผ ๊ต์ฒดํ๋ ์ฑ
์์ด ์๋ NavHostFragment๋ฅผ ํฌํจํจ.
์ฌ๋ฌ ์กํฐ๋นํฐ ๋ชฉ์ ์ง๋ฅผ ๊ฐ์ง ์ฑ์ ๊ฒฝ์ฐ ๊ฐ ์กํฐ๋นํฐ๋ ์์ฒด ๋ด๋น๊ฒ์ด์
๊ทธ๋ํ๋ฅผ ๊ฐ์ง๊ฒ ๋จ.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
.../>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
.../>
</androidx.constraintlayout.widget.ConstraintLayout>
๊ธฐ์กด ํ๋๊ทธ๋จผํธ๋ ์กํฐ๋นํฐ์์ ๋ชฉ์ ์ง ์์ฑ ๊ฐ๋ฅ. ๋ํ ๋ด๋น๊ฒ์ด์ ์๋ํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ชฉ์ ์ง๋ฅผ ๋ง๋ค๊ฑฐ๋ ๋์ค์ ํ๋๊ทธ๋จผํธ๋ ์กํฐ๋นํฐ๋ก ๋์ฒดํ ์ ์๋ ํ๋ ์ด์คํ๋๋ฅผ ๋ง๋ค ์ ์์.
๋ชฉ์ ์ง๋ก ์ด๋ํ๋ ๊ฒ์ NavController๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋๋ฉฐ, NavController๋ NavHost ๋ด์์ ์ฑ ๋ค๋น๊ฒ์ด์ ์ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด.
๊ฐ NavHost์๋ ๊ณ ์ ํ NavController๊ฐ ์์.
Kotlin:
Fragment.findNavController()
View.findNavController()
Activity.findNavController(viewId: Int)
Java:
NavHostFragment.findNavController(Fragment)
Navigation.findNavController(Activity, @IdRes int viewId)
Navigation.findNavController(View)
์์ ๋ฉ์๋๋ค ์ค ํ๋๋ฅผ ์ฌ์ฉํ์ฌ NavController๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์.
FragmentContainerView๋ฅผ ์ฌ์ฉํ์ฌ NavHostFragment๋ฅผ ๋ง๋ค๊ฑฐ๋ FragmentTransaction์ ํตํด ์๋์ผ๋ก NavHostFragment๋ฅผ ์กํฐ๋นํฐ์ ์ถ๊ฐํ ๋, ์กํฐ๋นํฐ์ onCreate()
์์ Navigation.findNavController(Activity, @IdRes int)๋ฅผ ์ฌ์ฉํ์ฌ NavController๋ฅผ ๊ฐ์ ธ์ค๋ ค๊ณ ํ๋ฉด ์คํจํ ์ ์์.
๋์ ์ง์ NavController๋ฅผ NavHostFragment์์ ๊ฐ์ ธ์์ผ ํจ.
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
๋ชฉ์ ์ง ์ฌ์ด๋ฅผ ์ด๋ํ ๋ ๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ์ Safe Args Gradle ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ ๊ฒ. ์ด ํ๋ฌ๊ทธ์ธ์ ๊ฐ๋จํ ๊ฐ์ฒด ๋ฐ ๋น๋ ํด๋์ค๋ฅผ ์์ฑํ์ฌ ๋ชฉ์ ์ง ๊ฐ ์์ ํ ํ์์ ๋ด๋น๊ฒ์ด์ ๊ณผ ์ธ์ ์ ๋ฌ์ ๊ฐ๋ฅํ๊ฒ ํจ.
Safe Args๋ฅผ ํ์ฑํํ๋ฉด ํด๋น ํ๋ฌ๊ทธ์ธ์ด ์ ์ํ ๊ฐ ์ก์
์ ๋ํ ํด๋์ค ๋ฐ ๋ฉ์๋๋ฅผ ์์ฑ.
Safe Args๋ ๋ชฉ์ ์ง์ ๋ํ ํด๋์ค๋ ์์ฑ. ์์ฑ๋ ํด๋์ค ์ด๋ฆ์ ๋ชฉ์ ์งํด๋์ค ์ด๋ฆ + Directions๋ผ๋ ๋จ์ด์ ์กฐํฉ.
(์: SpecifyAmountFragment ๊ฐ ๋ชฉ์ ์ง์ผ ๊ฒฝ์ฐ SpecifyAmountFragmentDirections๊ฐ ์์ฑ๋จ.)
์์ฑ๋ ํด๋์ค์ ๋ชฉ์ ์ง์ ์ ์๋ ๊ฐ ์ก์
์ ๋ํ ์ ์ ๋ฉ์๋ ํฌํจ. ์ด ๋ฉ์๋๋ ์ ์๋ ์ก์
๋งค๊ฐ๋ณ์๋ฅผ ์ธ์๋ก ์ฌ์ฉํ๊ณ navigate()
์ ์ ๋ฌํ ์ ์๋ NavDirections ๊ฐ์ฒด ๋ฐํ.
override fun onClick(view: View) {
val action =
SpecifyAmountFragmentDirections
.actionSpecifyAmountFragmentToConfirmationFragment()
view.findNavController().navigate(action)
}
๊ฐ์ฌํฉ๋๋ค. ์ด๋ฐ ์ ๋ณด๋ฅผ ๋๋ ์ฃผ์ ์ ์ข์์.