SW 공부노트
[안드로이드/Kotlin] Navigation (with 프래그먼트) 본문
Navigation
build.gradle(Module)
plugins{
...
id 'androidx.navigation.safeargs.kotlin'
}
// Navigation
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
build.gradle(Project)
buildscript{
ext.nav_version = "2.5.3"
dependencies {
classpath 'com.android.tools.build:gradle:7.2.0'
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}
1. navigation 파일 생성
- res 폴더에서 navigation 디렉터리 생성 후 nav_graph 파일 생성
- Design 탭에서 화면 생성 후 화살표로 이어 화면 간 이동 표시
- list -> add(arg: labe_name)
- list -> detail(arg: id, labe_name)
- detail -> add(arg: id, labe_name)
- 뒤로 가기 액션 설정
- popUpTo: BackStack에서 어디까지 이동할 것인지 결정하는 속성
- popUpToInclusive: popUpTo로 지정한 fragment까지 pop 할 것인지 정하는 속성
- 화면 간 인수 설정: 인수를 받는 프래그먼트의 <argument> 태그 내 작성
- 네비게이션에서 사용하는 데이터 클래스 인수는 Serialize 또는 Parcelize 처리가 되어있어야 한다.
<fragment
android:id="@+id/detailFragment"
android:name="com.example.toyproject1.ui.DetailFragment"
android:label="fragment_detail"
tools:layout="@layout/fragment_detail">
<argument
android:name="item"
app:argType="com.example.toyproject1.network.Item"/>
</fragment>
2. activity_main에 FragmentContainerView 추가
- id는 nav_host로 설정
- name = "androidx.navigation.fragment.NavHostFragment"
- navigation 관련 속성 설정
- app:defaultNavHost = "true"
- app:navGraph = "@navigation/nav_graph"
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:defaultNavHost = "true"
app:navGraph = "@navigation/nav_graph"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
3. MainActivity에서 navigation 관련 설정
- navController 변수 선언 및 지연초기화
- navHostFragment(탐색 그래프의 대상) 초기화 -> FragmentContainer id 전달
- 내비게이션바 설정 / 위로 작업 설정
class MainActivity : AppCompatActivity() {
private var binding: ActivityMainBinding? = null
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment
navController = navHostFragment.navController
setupActionBarWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
에러 error inflating class androidx.fragment.app.fragmentcontainerview navigation
-> nav_graph 파일에 잘못된 코드가 있어서 inflate 오류 발생
4. 화면 이동 코드 작성
- action 변수 사용
인수를 전달해야 하는 경우 action에 담아 전달
val action = MovieListFragmentDirections.actionMovieListFragmentToAddMovieFragment()
findNavController().navigate(action)
- action 변수 미사용
findNavController().navigate(R.id.action_movieListFragment_to_addMovieFragment)
5. 인수받기(SafeArgs)
인수를 받아야 하는 UI 클래스에서 인수가 담긴 객체를 생성한다.
val args: MainFragmentArgs by navArgs()
println(args.id) // args의 속성 통해 인수 사용
* 내비게이션 장점
- 프래그먼트의 트랜잭션 처리
- '위로', '뒤로' 작업을 올바르게 처리
- 애니메이션과 전환에 표준화된 리소스 제공
- 딥 링크 구현 및 처리
- Safe Args를 이용한 프래그먼트간 유형 안전성이 보장되는 데이터 전달 가능
- ViewModel을 활용해 UI 사이 데이터 공유 가능
+) 화면 별 라벨 지정 가능
내비게이션이나 뷰 바인딩 실습에 프래그먼트를 사용하면서 작업 순서 등이 헷갈려서 정리해보았다. 프래그먼트 사용 과정은 다음과 같으며, 뷰 바인딩, 내비게이션 관련 설정들도 함께 작성하였다.
1. 프래그먼트 파일(레이아웃 파일, 코틀린 클래스) 생성
2. 프래그먼트 코틀린 파일 설정
- onCreateView() 메서드 내에서 레이아웃 inflate
- 뷰 바인딩 사용할 경우 바인딩 변수 생성(null 허용 변수와 접근 가능 변수로 총 2개)
- onDestroyView() 메서드에서 바인딩 클래스 인스턴스에 대한 참조를 정리해야 하므로
null 허용 바인딩 변수에 null 값 넣어주기
3. Activity에 Fragment 띄우기
- activity_main 파일에 FragmentContainerView 추가해 액티비티 내에 프래그먼트 띄우기
-> 내비게이션 관련 속성(3개: name, defaultNavHost, navGraph) 지정
+) FrameLayout도 가능
4. MainActivity 설정
- 뷰 바인딩 사용할 경우 바인딩 설정 후 레이아웃 inflate
- supportFragmentManager.beginTransaction().add(R.id.컨테이너 아이디, 프래그먼트 변수) 통해 프래그먼트 연결
* 네비게이션을 사용할 경우, 따로 프래그먼트 연결해 줄 필요 없음 -> navController 설정이 필요하다면 여기에 작성
* 프래그먼트 트랜잭션은 프래그먼트를 추가, 삭제 및 교체하는 것을 뜻하지만, 프래그먼트 백 스택 관리, 프래그먼트 전환 애니메이션 등 다양한 일을 수행할 수 있다. 즉, 프래그먼트 내 구성요소들에 접근할 수 있게 해 준다. 이를 통해 액티비티에서 특정 이벤트가 발생했을 때, 프래그먼트에서 적절한 UI 동작을 할 수 있도록 구현해 준다.
'안드로이드 > 안드로이드 공부' 카테고리의 다른 글
[안드로이드/Kotlin] Retrofit 라이브러리 (0) | 2023.04.12 |
---|---|
[안드로이드/Kotlin] Binding(View, Data) (0) | 2023.04.12 |
[안드로이드/Kotlin] RecyclerView 정리(Adapter, 클릭 리스너) (0) | 2023.04.09 |
저장소 패턴(Repository pattern) (0) | 2023.04.05 |
[안드로이드] 활동 수명 주기 및 상태 (0) | 2023.03.13 |