일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 테스트
- Button
- binding
- 앱바
- TEST
- android
- CustomScrollView
- activity
- 계측
- viewmodel
- LifeCycle
- 앱
- livedata
- drift
- Coroutines
- intent
- Flutter
- Dialog
- data
- DART
- Kotlin
- textfield
- scroll
- appbar
- ScrollView
- Compose
- tabbar
- textview
- 안드로이드
- Navigation
- Today
- Total
Study Record
[안드로이드] Navigation (탐색) 살펴보기 본문
😶 Navigation 개요
화면(Activity)전환을 할 때 항상 Activity 를 앱 내의 여러 콘텐츠를 탐색할 때(ex. 여러 fragment 를 탐색) 사용할 수 있는 Navigation Component가 있다.
Navigation 에는 NavigationGraph , NavHost, NavController를 구성요소로 가지고 있다.
Navigation Graph(탐색 그래프)
탐색 그래프는 앱 탐색의 가상 매핑정보가 있어 각 대상(Activity, Fragment 등)이 서로 관련되는 방식을 보여주는 XML 이다.
NavHost
탐색 그래프에서 대상을 표시하는 빈 컨데이터로 NavHostFragment가 포함된다.
Nav Controller
NavController객체를 사용하면 NavHost에 표시되는 대상 간 탐색을 제어할 수 있다. 예를 들어, Activity내에서 NavController객체의 navigate() 메서드를 호출하여 Fragment를 교체할 수 있다.
😶 Navigation 활용하기
이 글에서 설명하는 예시는 한 Activity 에서 Fragment 간의 탐색 과정을 살펴본다.
기본 탐색의 과정은 StartFragment > workFragment > EndFirstFragment , EndSecondFragment > StartFragment 이다.
탐색을 설정하기 전, Navigation 을 사용하기 위해 dependency 를 추가해 준다.
dependencies {
implementation 'androidx.navigation:navigation-fragment-ktx:2.6.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.6.0'
}
1. dependency 추가 후 Navigation graph 파일을 만든다.
res/ 파일에 오른쪽 마우스 클릭 후 New > Android Resource Directory 생성 후 Resource type 을 navigation 으로 하고 이름을 Directory Name 을 navigation 인 디렉터리를 생성한다.
res/navigation/ 디렉터리에 새로운 파일 navigation.xml 을 생성한다. 이 파일은 Navigation graph 로써 기능한다. navigation.xml 파일을 수정하기 전, 탐색에 연결될 Fragment 들을 미리 생성한다.
2. Navgiation Graph 의 탐색을 추가한다.
2-1. fragment 추가하기
navigation.xml 파일에 splite 탭 혹은 design 탭을 누르면 위의 사진과 같은 부분을 누르면 연결을 추가할 Fragment 를 볼 수 있다. 사용할 Fragment 를 모두 클릭하면 자동으로 navigation.xml 파일에 fragment 가 추가된다.
<?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/navigation"
app:startDestination="@id/startFragment"
xmlns:tools="http://schemas.android.com/tools">
<fragment
android:id="@+id/startFragment"
android:name="com.example.test2.StartFragment"
android:label="StartFragment"
tools:layout="@layout/fragment_start"/>
...
</navigation>
만약 프레그먼트를 추가했는데 미리 보기 화면이 나오지 않는다면 tools:layout 속성을 이용하여 해당 레이아웃에 연결해 준다. tools 로 시작하는 속성들은 실제 실행되는 앱에 영향을 미치지 않는다.
2-2. fragment 사이에 연결(탐색) 설정하기
예시에서는 startFragment > workFragment 로 이동한다. 여기서 ">" 이동한다는 표시를 <fragment> 태그에 <action> 태그를 이용하여 나타낼 수 있다.
코드로 직접 작성하기보단 splite 혹은 design 탭에서 fragment 를 클릭하면 좌우 양쪽에 동그란 원 모양을 클릭하여 연결될 fragment 에 끌어다 놓으면 <action> 이 완성된다.
코드로 보면 다음과 같다. <action> 태그의 app:detination 속성이 연결될 fragment 이고 나중에 id 로 action 들을 구분하여 프로그래밍으로 다음 fragment 로 이동하라고 명령할 수 있다.
<?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/navigation"
app:startDestination="@id/startFragment"
xmlns:tools="http://schemas.android.com/tools">
<fragment
android:id="@+id/startFragment"
android:name="com.example.test2.StartFragment"
android:label="StartFragment"
tools:layout="@layout/fragment_start">
<action
android:id="@+id/action_startFragment_to_workFragment"
app:destination="@id/workFragment" />
</fragment>
</navigation>
2-3. Activity 에서 탐색 설정하기
Navigation 을 사용할 Acrivity 의 fragment 태그에 NavHostFragment 로 프래그먼트를 직접 적용해주고 app:navGraph 속성으로 Navigation graph(탐색이 설정된 xml 파일) 를 넣어준다. app:defaultNavHost 를 true 로 하면 기본적인 셋팅이 끝났다. defaultNavHost 값을 true 로 하면 프래그먼트 컨테이너가 탐색 계층 구조와 상호작용할 수 있다.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/main_fg"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:navGraph="@navigation/navigation"
app:defaultNavHost="true"/>
😶 다음 Fragment 로 넘어가기
StartFragment > WorkFragment 로 넘어가는 <action> 을 미리 navigation.xml 에 추가했었다. 이제 이 연결정보를 이용해서 현재 StartFragment 에서 WorkFragment 로 넘어가는 방법은 NavController 를 사용하면 된다.
NavController 를 가져오는 방법은 다음 3가지 방법이 있다.
Fragment.findNavController()
View.findNavController()
Activity.findNavController(viewId: Int)
NavController 를 가져오면, navigate(resId: int) 함수에 인자로 미리 경로가 설정된 navigation.xml 파일의 <action> 의 id 를 설정하면 바로 다음 Fragment 로 넘어간다.
예를 들어 StartFragment 의 button 을 눌렀을 때 WorkFragment 로 넘어가는 흐름이라면 다음과 같다.
binding.workBtn.setOnClickListener {
it.findNavController().navigate(R.id.action_startFragment_to_workFragment)
}
😶 Back Button 관리
안드로이드의 뒤로 가기 버튼을 눌렀을 때 Navigation 에서 관여할 수 있다. Fragment 의 이전 탐색 경로는 Back Stack 에 저장된다.
만약, 탐색 경로(Back Stack) 이 startFragment > workFragment > endFirstFragment 의 순서로 쌓여있다면, 다시 startFragment 로 탐색(이동)할 경우 startFragment > workFragment > endFirstFragment > startFragment 가 될 것이다. 즉, 현재 Fragment 에서 startFragment 가 쌓인다. 이 상태(startFragment)에서 뒤로가기 버튼을 누르면 endFirstFragment 로 돌아갈 것이다.
하지만 startFragment > workFragment > endFirstFragment 에서 startFragment 로 탐색할 때 이전 경로에 있던 endFirstFragment 와 workFragment 를 종료하고 startFragment 로 돌아가고 싶을 때가 있다. 이럴 때 사용할 수 있는 게 app:popUpTo 와 app:popUpToInclusive 속성이 있다.
app:popUpTo 는 특정 프래그먼트 id 값을 가질 수 있고 app:popUpToInclusive 는 true/false 값을 가질 수 있다. app:popUpTo="@id/startFragment" 라고 한다면 이전 탐색했던 경로 중 startFragment 가 있을 때까지 종료한다. 만약 app:popUpToInclusive 값이 true 라면 app:popUpTo 값의 startFragment 를 포함하여 종료하고 app:popUpToInclusive 갑이 false 이면 startFragment 를 남겨둔다.
현재 탐색 경로가 startFragment > workFragment > endFirstFragment 일 때 startFragment 로 다시 돌아가고 싶다면 app:destinaion="@id/startFragment", app:popUpTo="@id/startFragment", app:popUpToInclusive="true" 로 설정하면 된다.
안드로이드에서 Design 탭의 탐색 경로 화살표를 클릭하고 Attributes 의 Pop Behavior 에서 간단하게 설정할 수 있다.
'안드로이드' 카테고리의 다른 글
[안드로이드] Navigation 을 이용한 Fragment 데이터 전달, Safe Arg (0) | 2023.06.27 |
---|---|
[안드로이드] 앱바 Menu 추가하기 (+ Navigation) , drawer (0) | 2023.06.25 |
[안드로이드] Fragment 살펴보기 (0) | 2023.06.22 |
[안드로이드] 데이터 바인딩(Data binding)과 뷰 바인딩(View binding) (0) | 2023.06.19 |
[안드로이드] ConstraintLayout 살펴보기 (0) | 2023.06.17 |