Fragment에서 Fragment로 이동에 용이한 Navigation라이브러리 적용시켜보기
→ 해당 라이브러리를 사용하는 방법이 다소 어려워 이 영상을 시청하고 그대로 따라하면서 익혀보았다.
-> 결과물 부터 보고 싶다면 글 제일 아랫 부분으로 이동!
Navigation적용하는 이유
- 내가 현재 만들고있는 앱은 Single Activity - Multiple Fragments구조이기 때문에 Fragment탐색을 돕는 것에 초점이 맞춰져있는 Navigation라이브러리를 적용하는 것이 좋다
- 화면 전환 시 Fragment tansaction을 다루지 않아도 된다.
- 화면 전환 시에 필요한 Back/Up 동작을 기본적으로 지원하기 때문에 수고로움을 줄여준다.
Navigation을 구성하는 요소
- NavHost
- NavController를 가지고 있는 컨테이너
- NavController
- NavGraph를 다루는 곳
- NavGraph
- Destination 목록을 가지고 있음
- XML로 작성된다
Navigation적용하기
우선 해당 라이브러리에 관한 gradle세팅부터 시작!
Navigation Component에 대한 dependencies를 추가해주자.
// Module level build.gradle
dependencies {
...
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
...
}
그리고 Safe args Plugin을 추가하자.
// Project level build.gradle
buildscript {
ext.nav_version = "2.3.0"
dependencies {
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.3.0")
}
}
// Module level build.gradle
plugins {
id 'androidx.navigation.safeargs'
}
💡 만약 Safe Args플러그인이 제대로 세팅되지 않으면, ~FragmentDirections 이 제대로 만들어지지 않는다.
- NavDirections는 Activity 실행과 비교하면 Intent와 비슷히다.
- NavDirections는 개발자가 직접 작성하는 것은 아니고, Navigation에 의해 자동 생성되는 클래스다.
activity_main.xml에 NavHostFragment를 지정해주자
→ FragmentContainerView: Activity에서 Fragment를 호스팅하는 일반적인 패턴 중 하나
activity_main.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"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>
- app:defaultNavHost="true" : fragment이동 했을 때 back버튼을 누르면 다시 되돌아올 수 있도록 만들어 준다
- app:navGraph="@navigation/nav_graph" : nav_graph.xml에 지정된 startDestination이다.
- nav_graph는 아직 생성이 안된상태! 이제 생성해주러 가자~
Navigation을 총괄하기 위한 nav_graph.xml파일을 만들자
주의 : layout폴더에서 우클릭 하여 만드는 것이 아니라 최상위 폴더인 res폴더에서 우클릭하여 xml파일 만들어야 한다!
이때 Resource type을 Navigation으로 지정하자!
그러면 다음과 같은 파일이 생성된다.
<?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"
android:id="@+id/nav_graph">
</navigation>
이제 Fragment와 해당 Fragment의 xml을 생성하자.
→ HomeFragment.kt 그리고 fragment_home.xml 생성
그리고 nav_graph.xml로 돌아가서 생성한 Fragment를 추가해주자!
그런데 위와 같이 이미지가 잘 뜨지 않는걸 확인할 수 있다.
만약 이를 수정해주고 싶다면 fragment_home.xml로 돌아가서 fragment태그에 다음의 속성을 추가해주자.
tools:layout="@layout/fragment_home"
이제 fragment를 클릭하여 추가해주자!
그러면 이와 같이 집 모양의 아이콘이 붙으며 추가되는걸 확인할 수 있다.
이는 제일 처음 추가되었기 때문에 바로 Starting Destination으로 지정된 것이다.
(만약 Starting Destination을 바꾸고 싶다면 상단 바에 있는 집 모양 아이콘을 클릭하여 전환시키면 된다.)
두 번째 Fragment를 생성해주고 nav_graph.xml에 추가
action을 만들어주기 위해 다음과 같이 연결
만들어진 action태그에 슬라이드 액션 추가해주기
<action
android:id="@+id/action_homeFragment_to_loginFragment"
app:destination="@id/loginFragment"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
nav_graph.xml 전체코드
<?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/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="org.techtown.navigatorfunction.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home"
>
<action
android:id="@+id/action_homeFragment_to_loginFragment"
app:destination="@id/loginFragment"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
</fragment>
<fragment
android:id="@+id/loginFragment"
android:name="org.techtown.navigatorfunction.LoginFragment"
android:label="fragment_login"
tools:layout="@layout/fragment_login"
/>
</navigation>
HomeFragment.kt로 가서 버튼을 눌렀을 때의 동작을 구현
onCreateView를 사용하여 반드시 view를 생성 및 return해주어야 한다
onViewCreated를 사용하여 setOnClickListener구현
HomeFragment.kt 전체코드
class HomeFragment: Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonLogin.setOnClickListener{
val action = HomeFragmentDirections.actionHomeFragmentToLoginFragment()
findNavController().navigate(action)
}
}
}
결과물
느낀 점 🤔
Fragment에서 Fragment로 이동할 수 있게 해주는 Navigator에 대해 학습해보았다.
처음엔 이리저리 검색만 해보았는데 전혀 감이 잡히지 않았었다.
그러던 중 Youtube로 설명해주는 강의를 찾았는데, 역시나 영상으로 확인하니 훨씬 쉽게 다가왔다.
그런데 해당 개념을 내 프로젝트에 바로 적용하려니 자꾸만 헷갈리고 어디서부터 건들여야할지 또 고민이었다.
그래서 그냥 아예 Navigator를 공부하기 위한 용도로 Android프로젝트를 새로 생성해서 학습하였다.
그랬더니 훨씬 보기도 쉽고 학습하기 수월하였다.
앞으로도 이렇게해야지!
제 글이 당신에게 도움이 되었길 바랍니다.
추가적인 질문은 언제든지 환영해요.
인상깊게 보셨다면 아래 광고 한 번만 클릭해주세요! 정말 큰 힘이 됩니다~! 🤠
'📜 TIL' 카테고리의 다른 글
Soft Keyboard(virtual keyboard) 띄워졌을 때 키보드 바로 위에 버튼이 보여지도록 만들기 (0) | 2023.03.10 |
---|---|
[Android] NullPointerException -ViewTreeObserver.dispatchOnGlobalLayout (0) | 2023.03.06 |
[Android] 서버 로그인 시 비밀번호 암호화 적용해주기 (0) | 2023.02.27 |
[Android] 안드로이드 개발자 면접질문 정리 part 1 (0) | 2023.02.22 |
[Android] Retrofit활용해 서버와 통신 및 okHttp로 로그찍어보기 (0) | 2023.02.20 |