안녕하세요! 이번 포스팅은 Jetpack Navigation 을 이용한 간단한 화면 이동을 구현해 보았습니당~
Jetpack Navigation
Jetpack 은 Android 개발을 빠르게 도와주는 컴포넌트 라이브러리입니다.
Jetpack Navigation 은 UI 를 통한 Navigation 편집이 가능하게 해주는 라이브러리로, 구글에서 권장하고 있는 네비게이션 중 하나입니다.
단순한 버튼 클릭부터 좀 더 복잡한 패턴(앱바, 탐색 창)에 이르기까지 여러 가지 탐색을 구현하도록 도와줍니다.
탐색 구성요소는 기존의 원칙을 준수하여 일관적이고 예측 가능한 사용자 환경을 보장합니다.
🚨 Jetpack Navigation 의 3가지 주요 구성요소
1. 탐색 그래프
: 모든 탐색 관련 정보가 모여있는 xml 리소스. 이용가능한 경로가 포함되어있다.
2. NavHost
: 탐색 그래프에서 대상을 표시하는 빈 컨테이너.
프래그먼트 대상을 표시하는 기본 NavHost 구현인 NavHostFragment 가 포함된다.
3. NavController
: NavHost 에서 탐색을 관리하는 객체.
사용자가 앱 내에서 이동할 때 NavHost 에서 대상 콘텐츠를 전환하는 작업을 한다.
https://developer.android.com/guide/navigation
https://developer.android.com/guide/navigation/navigation-ui?hl=ko
💡 작성한 파일 목록 입니다.
1. build.gradle(:app)
2. res/navigation/nav_graph.xml
3. NavMainActivity.kt
4. res/layout/activity_nav_main.xml
5. OneFragment.kt (TwoFragment.kt, ThreeFragment.kt)
6. res/layout/fragment_one.xml (fragment_one)
1. build.gradle(:app)
viewBinding 을 사용하기 위해 viewBinding = true 를 추가하여 enable 할 수 있도록 하였고,
Jatpack Navigation 에 대한 의존성을 추가해줍니다.
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
...
buildFeatures {
viewBinding = true
}
...
}
dependencies {
...
// Jetpack Navigation
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
...
}
2. res/navigation/nav_graph.xml
res 경로에서 New > Directory 를 클릭하여 navigation 폴더를 생성하고,
nav_graph.xml 을 생성합니다.
nav_graph.xml 는 Navigation 탐색 그래프 가 됩니다.
탐색 그래프를 통해 앱 내에서 사용자가 이용 가능한 모든 경로가 표시됩니다.
제가 작성한 코드는 OneFragment -> TwoFragment -> ThreeFragment -> OneFragment 순서로 순환하도록 Navigation 기능을 작성하였습니다.
app:startDestination="@id/fragmentOne" 는 navi 의 처음 시작점을 나타냅니다.
<fragment> 태그안에서
어떤 프래그먼트를 사용하는지 명시해줍니다.(name, layout)
레이아웃을 매핑해서 디자인에서 화면을 확인할 수 있도록 합니다.
fragment 안에는 action, argument, deeplink 태그를 가질 수 있습니다.
action 은 화살표로 화면간의 이동을 나타내고, argument 는 데이터 전달 시 사용합니다.
<?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/fragmentOne">
<fragment
android:id="@+id/fragmentOne"
android:name="com.eun.myappkotlin02.nav.OneFragment"
android:label="fragment_one"
tools:layout="@layout/fragment_one" >
<action
android:id="@+id/action_fragmentOne_to_fragmentTwo"
app:destination="@id/fragmentTwo" />
</fragment>
<fragment
android:id="@+id/fragmentTwo"
android:name="com.eun.myappkotlin02.nav.TwoFragment"
android:label="fragment_two"
tools:layout="@layout/fragment_two" >
<action
android:id="@+id/action_fragmentTwo_to_fragmentThree"
app:destination="@id/fragmentThree" />
</fragment>
<fragment
android:id="@+id/fragmentThree"
android:name="com.eun.myappkotlin02.nav.ThreeFragment"
android:label="fragment_three"
tools:layout="@layout/fragment_three" >
<action
android:id="@+id/action_fragmentThree_to_fragmentOne"
app:destination="@id/fragmentOne" />
</fragment>
</navigation>
3. NavMainActivity.kt
package com.eun.myappkotlin02.nav
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.eun.myappkotlin02.databinding.ActivityNavMainBinding
class NavMainActivity: AppCompatActivity() {
companion object {
const val TAG = "NaviMainActivity"
}
lateinit var binding: ActivityNavMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNavMainBinding.inflate(layoutInflater)
setContentView(binding.root) //setContentView(R.layout.activity_navi_main.xml)
}
}
4. activity_nav_main.xml
NavMainActivity.kt 에 대한 레이아웃 리소스입니다.
activity_nav_main.xml 에 NavHost 에 대한 정의를 합니다.
<FragmentContainerView> 태그 안에
프래그먼트 대상을 표시하는 기본 NavHost 구현인 NavHostFragment 가 포함되도록
android:name="androidx.navigation.fragment.NavHostFragment" 코드를 추가합니다.
app:defaultNavHost="true" 코드는
시스템의 백버튼 등의 이벤트가 그래프와 연동이 되도록 합니다.
true 로 설정하지 않을 경우 백버튼 시 앱이 종료됩니다.
app:navGraph="@navigation/nav_graph" 코드는 어떤 Navigation 탐색 그래프를 사용하는지 명시해줍니다.
Toolbar 은 어떤 fragment 에서든 표시되도록 추가하였습니다.
<?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=".nav.NavMainActivity">
<Toolbar
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/blue_light"
android:elevation="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/naviHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
5. OneFragment.kt
NavController 를 통해 NavHost 에서 콘텐츠를 전환할 수 있도록 합니다.
OneFragment 의 NavController 는 Navigation.findNavController(binding.root).navigate(R.id.action_fragmentOne_to_fragmentTwo) 로,
TwoFragment 의 NavController 는 Navigation.findNavController(binding.root).navigate(R.id.action_fragmentTwo_to_fragmentThree) 로,
ThreeFragment 의 NavController 는 Navigation.findNavController(binding.root).navigate(R.id.action_fragmentThree_to_fragmentOne) 로
설정합니다.
TwoFragment.kt, ThreeFragment.kt 도 다음과 같습니다.
package com.eun.myappkotlin02.nav
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import com.eun.myappkotlin02.R
import com.eun.myappkotlin02.databinding.FragmentOneBinding
class OneFragment: Fragment() {
private lateinit var binding: FragmentOneBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// return super.onCreateView(inflater, container, savedInstanceState)
binding = FragmentOneBinding.inflate(inflater, container, false)
initView()
return binding?.root
}
private fun initView() = with(binding) {
binding.btnGo.setOnClickListener {
Navigation.findNavController(binding.root).navigate(R.id.action_fragmentOne_to_fragmentTwo)
}
}
}
6. fragment_one.xml
OneFragment 에 대한 레이아웃 리소스입니다.
TwoFragment, ThreeFragment 에 대한 레이아웃 리소스 fragment_two.xml, fragment_three.xml 도 다음과 같습니다.
<?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">
<TextView
android:id="@+id/tv_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="One"
android:textAlignment="center"
android:textSize="100sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="go Two"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_one" />
</androidx.constraintlayout.widget.ConstraintLayout>
결과 화면
One 화면에서 Go Two 버튼 클릭 시 Two 화면으로 이동,
Two 화면에서 Go Three 버튼 클릭 시 Three 화면으로 이동,
Three 화면에서 Go One 버튼 클릭 시 One 화면으로 이동합니다.
감사합니당 (✿◠‿◠)
'📱 안드로이드 Android ~ Kotlin' 카테고리의 다른 글
[Android/kotlin] 구글 Firebase Realtime Database 사용하기 (0) | 2022.06.10 |
---|---|
[Android/kotlin] 구글 Firebase Crashlytics 사용하기 (0) | 2022.06.09 |
[Android/Kotiln] 생체 인식 인증 방식 Biometric 사용하기 (3) | 2022.04.28 |
[Kotlin/코틀린] 5 - 상속과 클래스 종류 (data 클래스, object 클래스, companion 클래스) (1) | 2022.02.04 |
[Kotlin/코틀린] 4 - 널(null) 안전성 (0) | 2022.02.04 |