네비게이션은 안드로이드 개발의 트렌트인 single activtiy - multiple fragment 형태를 위하여 nav_graph.xml을 통하여 화면 전환을 할 수 있게 해주는 라이브러리다.
즉 Navigation Graph에서 특정 경로 이동을 Controller에게 전달하고, 이 Navigation Controller가 Navigation Host에 적절한 대상을 표시한다.
공식 문서를 토대로 초기설정을 해준다
https://developer.android.com/jetpack/androidx/releases/navigation#declaring_dependencies
build.grade(Modlue: Name)파일에
의존성을 주입해주고
//navigation
def nav_version = "2.5.3"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
plugin에 safeargs를 추가해준다.
id 'androidx.navigation.safeargs.kotlin'
build.gradle(Project: Name)
파일 최상단에 buildscript를 아래와 같이 추가해준다.
buildscript {
repositories {
google()
}
dependencies {
def nav_version = "2.5.2"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}
안드로이드는 시간에 따라 gradle 파일 설정도 매번 바뀌고 버전 업그레이드도 상시 있어서 현재 버전에 맞게 입력을 해줘야할 것 같다.
원래는 maven(), google() 라이브러리도 import가 되어있지 않으면 build.gradle(Project: Name)에 써줘야 한다고 많은 문서에서 나와있는데 settings.gradle 파일에 pluginManagement에 명시가 되어있는 듯 하다.
app->new->android resource file로 가 아래와 같이 nav_graph 리소스 파일을 생성한다.
그리고 사용할 activity에서 design 뷰로 NavHostFragment를 화면에 드래그 해주면
안스가 자동으로 nav_graph를 인식하여 제안해준다. ok를 눌러 가져온다.
그리고 constraint를 주기 위하여 디자인 모드에서 fragmentContainerView의 (Infer Constraints)를 누르고 constraints를 적용해준다.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainerView2"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
app:defaultNavHost="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
nav_graph의 가운데의 추가 버튼을 눌러 프래그먼트를 생성한다. 생성한 프래그먼트를 더블클릭하면 xml 파일로 이동하여 바로 편집할 수 있다.
xml을 위와같이 만들어 실행하면 main_xml에 놓은 fragment_xml 파일이 보여지게 된다.
※데이터 바인딩을 위하여 xml 파일을 layout 태그로 묶어주는 것을 잊지 말자
이미 있는 fragment를 nav_graph에 넣을 때 레이아웃이 안보이는 문제가 종종 생긴다
xmlns:tools="http://schemas.android.com/tools"
nav_graph.xml 상단의 tools가 xmlns:tools="http://schemas.android.com/res-auto" 가 아닌
xmlns:tools="http://schemas.android.com/tools" 로 지정되어있는지 확인해주고
그 안에 fragment 태그들의 tools들이
tools:layout="@layout/fragment_home"
과 같이 레이아웃이 정의되어있는지 확인하고 없으면 넣어준다.
nav_graph에 프래그먼트를 추가하면서 Homefragment.kt 파일이 자동으로 생성된 것을 볼 수 있는데
액티비티와 마찬가지로 데이터바인딩을 해준다.
class HomeFragment : Fragment() {
private lateinit var binding : FragmentHomeBinding ...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
binding = DataBindingUtil.inflate(inflater,R.layout.fragment_home, container, false)
return binding.root
} ...
기존에 있는 onCreate함수를 지우고 onCreateView에 데이터를 바인딩 하였다.
액티비티는 binding.root를 return 할 필요가 없는데 반면 fragment는 binding.root를 반환해주어야 한다.
마찬가지 방법으로 nav_graph에서 fragment를 하나 더 추가해 편집 후 kt 파일을 수정하였다.
package com.example.navdemo
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import com.example.navdemo.databinding.FragmentSecondBinding
class SecondFragment : Fragment() {
private lateinit var binding: FragmentSecondBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
binding = DataBindingUtil.inflate(inflater,R.layout.fragment_second, container, false)
return binding.root
}
}