탐색 그래프는 fragment 간 탐색을 구현하는 데 도움이 되는 시각적 편집기다. 각 화면의 관계를 XML 파일로 나타낸다.
MainActivity에서 FragmentContainerView 사용하도록 수정해보자.
탐색 그래프를 사용하기 위해 gradle 설정은 이 페이지를 참고
Android Studio Bumblebee나 Chipmunk 버전에서는 build.gradle와 settings.gradle 구조가 코드랩 강의와 좀 다르다.
build.gradle (project 수준)
여기에 nav_version과 safe args 플러그인에 대한 buildscript를 작성한다. SafeArgs는 프래그먼트 간 데이터를 전달할 때 유형 안전성을 지원한다.
buildscript는 plugins 보다 위에 작성되어야 한다.
buildscript {
ext{
nav_version = "2.4.1"
}
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}
plugins {
...
id 'androidx.navigation.safeargs.kotlin' version '2.4.1' apply(false)
}
build.gradle (module 수준)
fragment와 navigation을 사용하기 위한 plugins와 dependecies를 추가한다.
plugins {
id 'androidx.navigation.safeargs.kotlin'
}
dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}
주의
위에 작성된 dependency나 plugin의 버전이 서로 다르면 빌드에러가 발생할 수 있다.
버전이 동일한지 확인하자.
FragmentContainterView 설정
RecyclerView
를 FragmentContainerView
로 변경한다.
NavHostFragment 설정
ID 속성 아래에 name 속성을 추가하고 androidx.navigation.fragment.NavHostFragment
로 설정한다. 이 속성의 특정 프래그먼트를 지정할 수 있지만 NavHostFragment
로 설정하면 FragmentContainerView
가 프래그먼트 간에 탐색을 할 수 있다.
navHost 설정
app:navHost
라는 속성을 추가하고 "true"
로 설정한다. 이렇게하면 Fragment Container가 탐색 계층 구조와 상호작용할 수 있다.
nav_graph 생성
app:navGraph="@navigation/nav_graph"
작성하고, Android Resource File을 추가해 Navigation
유형의 nav_graph.xml
을 생성한다.
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
action 연결
New Resource File
-> Navigation 타입
으로 nav_graph.xml
생성하면 시각적 편집기가 생성된다. 여기서 새로 만들기 버튼을 눌러 각 fragment 대상을 만들고 탐색 작업을 나타내도록 화살표를 이어준다.
전달할 Arguments 추가
인텐트에서 선택한 알파벳을 전달했었다. 여기서도 마찬가지로 wordListFragment에 전달할 Arguments
를 만든다. 오른쪽에 Arguments +
를 선택해 String
타입 letter
를 생성할 수 있다.
시작 대상 설정
FragmentContainerView
에 Assign start destination
setOnClickListener
에 탐색 작업에 대한 내용을 추가한다. holder.button.setOnClickListener {
val action = LetterListFragmentDirections
.actionLetterListFragmentToWordListFragment(letter = holder.button.text.toString())
holder.view.findNavController().navigate(action)
}
RecyclerView
가 아니라 NavController
를 사용해야 한다.
onCreate()
를 수정하고 onSupportNavigateUp()
메서드를 구현한다.
xml에서 작성한 FragmentContainerView(nav_host_fragment)를 가져와서 navController에 할당한다.
setupActionBarWithNavController()로 앱 바를 표시한다.
마지막으로 onSupportNavigationUp()은 뒤로가기 버튼 처리에 사용된다. 참고로 navigationUp()은 실패할 수 있으므로 성공 여부에 따라 boolean을 반환한다. 즉 navigationUp()이 false인 경우에만 super.onSupportNavigateUp()이 호출된다.
class MainActivity : AppCompatActivity() {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
setupActionBarWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
activity?.intent
를 참조해서 letter
extra에 액세스 했던 방식을 수정한다. letterId
를 lateinit
으로 만들고, onCreate()
에서 인수를 가져오는 코드를 작성한다.
onViewCreated()의 activity?.intent?.extras?.getString(LETTER).toString()을 letterId로 바꾼다.
앱 바에 표시되는 글자는 nav_graph.xml
에서 label 속성에서 설정할 수 있다.
strings.xml
에 wordListFragment
의 라벨이 될 텍스트를 추가하고,
<string name="word_list_fragment_label">Words That Start With {letter}</string>
nav_graph.xml
에서 label
속성을 수정한다.
이제 인텐트 없이 하나의 activity에서 두 화면 간 이동이 가능하다!
navigation에 대해 좀 더 알아보자.
Basic Activity 템플릿
을 생성하면 버튼으로 fragment 두 개가 왔다갔다하는 어플이 만들어진다.
nav_graph.xml
을 살펴보자.
Navigation Drawer Activity 템플릿
을 생성한다.
계층 구조를 확인하려면 tools > Layout Inspector
를 연다.
NavHostFragment
: Container for destinations
NavController
: Conduct navigation 실제 탐색 작업을 하는 역할
NavigationView
: Menu for Drawerlayout. destination들을 보여주는 네비게이션 바인데 탐색 구성요소는 아님. 탐색 구성요소의 항목들과 상호작용하는 것..
NavigationUI
: Updates content outside NavHostFragment. NavigationView나 BottomNavBar처럼 NavHostFragment의 바깥에 있지만 NavHostFragment의 변화에 따라 업데이트 되어야 하는 것들 업데이트하는 역할