Jetpack에서 Navigation을 한번 사용해보겠습니다
Navigation에 관해선 아래의 공식문서를 참고했어요
https://developer.android.com/guide/navigation
Navigation에는 3가지 Key part가 있습니다
1️⃣ Navigation Graph
모든 네비게이션 관련 정보가 한곳에 모여 있는 XML 리소스
앱을 통해 이동할 수 있는 경로뿐만 아니라 앱 내의 모든 개별 콘텐츠 영역(목적지)가 포함됩니다
2️⃣ Nav Host
Navigation graph로부터 목적지들을 표시하는 빈 컨테이너입니다
프래그먼트 목적지를 표시하는 기본 NavHost 구현인 NavHostFragment가 Navigation 구성요소에 포함됩니다
3️⃣ Nav Controller
NavHost 내에서 Navigation을 관리하는 객체입니다
NavController는 사용자가 앱 내에서 이동 시 NavHost에서 목적지 변경을 조정합니다
💡 Navigation의 장점
- Handling fragment transactions.
- Handling Up and Back actions correctly by default.
- Providing standardized resources for animations and transitions.
- Implementing and handling deep linking.
- Including Navigation UI patterns, such as navigation drawers and bottom navigation, with minimal additional work.
- Safe Args - a Gradle plugin that provides type safety when navigating and passing data between destinations.
- ViewModel support - you can scope a ViewModel to a navigation graph to share UI-related data between the graph's destinations.
0. 라이브러리 추가
dependencies {
val nav_version = "2.5.3"
// Java language implementation
implementation("androidx.navigation:navigation-fragment:$nav_version")
implementation("androidx.navigation:navigation-ui:$nav_version")
// Kotlin
implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
implementation("androidx.navigation:navigation-ui-ktx:$nav_version")
// Feature module Support
implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")
// Testing Navigation
androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")
// Jetpack Compose Integration
implementation("androidx.navigation:navigation-compose:$nav_version")
}
buildscript {
repositories {
google()
}
dependencies {
val nav_version = "2.5.3"
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version")
}
}
plugins {
id("androidx.navigation.safeargs")
}
1. res -> navigation resource type으로 파일 생성
res / navigation / 설정한 파일명으로 생성되어있음
2. 메인 프래그먼트, 이동할 프래그먼트들 생성
별 다른건 없어요.. 저는 이동할 프래그먼트는 2개 생성할거라 아래와 같이 만들었습니다
못쉥겨도 이해해주세요 간단한 예제니까요
3. 메인 액티비티에 NavHostFragment 붙이기
여기선 싱글 액티비티로 사용할거기 때문에, 메인 액티비티에 NavHostFragment를 붙여줍니다
NavHost를 Activity에 붙여주는 작업이에요 !
✨ 처음 접하니까 여기서부터 정신차리지 않으면 뒤에서 헷갈리더라구여
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
하나씩 보자면
app:defaultNavHost = 여러 navHost 중 하나만 true를 사용할 수 있고, Back버튼을 가로챕니다
app:navGraph = navigation 안에 어떤 파일을 쓸건지 명시
4. nav_graph에서 화면 목적지 정하기
+ 버튼으로 화면을 가져올 수 있고, 화면을 누르면 동그라면 저런 버튼이 나오는데, 저걸 끌면 화면에 연결할 수 있어요 :)
5. nav_graph 확인
저렇게 레이아웃을 끌어두면 아래와 같이 코드가 자동으로 생성됩니다 !
원래 action의 android:id가 아주 길게 생성되는데, 저는 그냥 제가 편한대로 네이밍했어요
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/mainFragment">
<fragment
android:id="@+id/mainFragment"
android:name="kong.droid.jetpacknavi.MainFragment"
android:label="MainFragment"
tools:layout="@layout/main_fragment">
<action
android:id="@+id/toGrid"
app:destination="@id/gridFragment" />
<action
android:id="@+id/toList"
app:destination="@id/listFragment" />
</fragment>
<fragment
android:id="@+id/gridFragment"
android:name="kong.droid.jetpacknavi.GridFragment"
android:label="GridFragment"
tools:layout="@layout/fragment_grid" />
<fragment
android:id="@+id/listFragment"
android:name="kong.droid.jetpacknavi.ListFragment"
android:label="ListFragment"
tools:layout="@layout/fragment_list" />
</navigation>
6. mainActivity에서 navController 생성하기
여기서 꼭 navController를 명시해줘야합니다
아니면 Fragment에서 navController를 가져와서 사용할 때 에러가 나더라구요
lateinit var navController: NavController
lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(LayoutInflater.from(this@MainActivity))
setContentView(binding.root)
navController = binding.fragmentContainerView.getFragment<NavHostFragment>().navController
}
7. mainFragment에서 이동 연결하기
저는 데이터바인딩을 사용했기 때문에, 이렇게 선언해두고 xml에 연결시켰어요
findNavController()시 Activity에서 navController가 뭔지 명시해두지 않으면 Exception 발생하니 주의하세요
fun moveToList(view: TextView) {
val action =
MainFragmentDirections
.toList()
view.findNavController().navigate(action)
}
fun moveToGrid(view: TextView) {
val action =
MainFragmentDirections
.toGrid()
view.findNavController().navigate(action)
}
기본 이동만 붙이고, 애니메이션, args 전달은 아직 적용해보지 않았습니다
2탄으로 돌아올게요
1탄의 소스는 아래에 있습니다 :)
https://github.com/eunie9498/JetpackExam
jetpack navigation 처음해보는데 싱글 액티비티 권장하는 요즘이니 익혀두면 좋을거같아요
그리고 재밌네요 ㅎㅎ
'📱 Android' 카테고리의 다른 글
[Android] Livedata setValue, postvalue (0) | 2023.06.23 |
---|---|
[Jetpack] Navigation Component #2 args 전달하기 (0) | 2023.05.01 |
[Jetpack] LiveData와 ViewModel (0) | 2023.03.23 |
[Hilt] Hilt 익히기 #2 - Dagger 복습하기 (주요 Annotation) (0) | 2023.01.30 |
[Android] Clean Architecture (0) | 2023.01.08 |