일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 막내의막무가내 일상
- 막내의막무가내 플러터
- 막내의막무가내 목표 및 회고
- 주택가 잠실새내
- 막내의막무가내 알고리즘
- 프로그래머스 알고리즘
- 막내의막무가내 안드로이드 코틀린
- 안드로이드
- 막내의 막무가내 알고리즘
- 막내의막무가내 코틀린
- 주엽역 생활맥주
- 막내의막무가내 안드로이드
- 안드로이드 sunflower
- 안드로이드 Sunflower 스터디
- 막내의 막무가내
- Fragment
- 막내의막무가내
- 막내의막무가내 rxjava
- 막내의막무가내 SQL
- 프래그먼트
- 막내의막무가내 코틀린 안드로이드
- 부스트코스
- 막내의막무가내 안드로이드 에러 해결
- 막내의막무가내 프로그래밍
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 플러터 flutter
- 막무가내
- 2022년 6월 일상
- 부스트코스에이스
- flutter network call
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] Android Jetpack Navigation 정리 및 BottomNavigationView 에 적용 + ActionBar 적용 (Kotlin) 본문
[안드로이드] Android Jetpack Navigation 정리 및 BottomNavigationView 에 적용 + ActionBar 적용 (Kotlin)
막무가내막내 2020. 4. 29. 17:56[2021-03-30 업데이트]
안드로이드 코틀린 Jetpack 라이브러리들에 대해 공부중이고 Jetpack Naviagtion 중 Bottom navigation 을 프로젝트에 간단하게 적용해볼려 하고있습니다.
보면서 도움이 되는 사이트를 기록합니다.
0. 공식문서
https://developer.android.com/guide/navigation/
1. 코드랩
2. 유용한 글
https://android.jlelse.eu/beginners-guide-to-bottom-navigation-with-android-jetpack-5485d2b8bbb5
https://medium.com/@maryangmin/navigation-components-in-android-jetpack-1-introduction-e38442f70f
일단은 ONE 액티비티에 THREE 프래그먼트 구조의 간단한 공부용 토이 프로젝트에 적용해봤습니다.
액티비티의 BottomNavigationView와 프래그먼트를 연결하는 작업을 해봤습니다. 간단하게 정리해봅니다.
개념과 다양한 기능 및 특징은 위 사이트들을 참고하고 공부합니다.
밑 사진은 공식문서에서 간단하게 요약정리가 잘 되어 있어 들고와봤습니다. 저 3가지 핵심요소 NavHost, NavController, 탐색그래프(NavGraph) 는 필히 아셔야 합니다.
0. 번들같이 값을 전달하는 작업이 없고 바텀네비게이션뷰를 이용한 프래그먼트 swap만 할 것이므로 다음 디펜던시만 추가해주면됩니다. 전자의 작업이나 다른 작업할 시 추가로 다른 디펜던시를 추가해야합니다.
// navigation
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
// For BottomNavigationView from Material Components
implementation 'com.google.android.material:material:1.1.0'
1. 먼저 아래와 같이 3개의 프래그먼트와 하나의 액티비티가 있습니다.
2. 액티비티의 xml 입니다.
프레임레이아웃 안에 프래그먼트를 넣고 name을 android:name="androidx.navigation.fragment.NavHostFragment" 로 설정합니다. 호스트 역할을 할 것입니다. (메인역할) 즉 메인 액티비티는 Content와 Navigation Method는 모두 NavHost 라는 Fragment에게 위임합니다.
메인 액티비티의 xml 은 싱글 액티비티 구성일 경우 Global 한 네비게이션을 가지는 역할을 합니다.
app:defaultNavHost="true" 을 함으로써 뒤로가기 버튼 클릭시 NavHostFragment 로 돌아옵니다. 안할 경우 뒤로가기
버튼 클릭시 호스트화면으로 안가고 바로 앱이 종료될 것 입니다.
app:navGraph="@navigation/bottom_nav_graph" NavHostFragment 와 설정한 네비게이션 그래프를 연결(연관)시켜줍니다. 네비게이션 그래프는이 NavHostFragment에서 사용자가 탐색 할 수있는 모든 목적지를 지정합니다
NavHostFragment 에대해선 다음을 참고합니다.
https://developer.android.com/reference/androidx/navigation/fragment/NavHostFragment
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".views.MainActivity">
<FrameLayout
android:id="@+id/main_fl_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/main_bottom_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<fragment
android:id="@+id/main_nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/bottom_nav_graph" />
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/main_bottom_navigation"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/colorWhiteBlue"
app:itemIconTint="@color/colorWhite"
app:itemTextColor="@color/colorWhite"
app:layout_behavior="tech.thdev.app.view.BottomNavigationBehavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/main_fl_container"
app:menu="@menu/bottom_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
3. 네비게이션 그래프 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"
app:startDestination="@id/countryFragment">
<fragment
android:id="@+id/countryFragment"
android:name="com.mtjin.coronakorea.views.country.CountryFragment"
android:label="CountryFragment"
tools:layout="@layout/fragment_country" />
<fragment
android:id="@+id/cityFragment"
android:name="com.mtjin.coronakorea.views.city.CityFragment"
android:label="CityFragment"
tools:layout="@layout/fragment_city" />
<fragment
android:id="@+id/updateFragment"
android:name="com.mtjin.coronakorea.views.update.UpdateFragment"
android:label="updateFragment"
tools:layout="@layout/fragment_update" />
</navigation>
직접 xml로 추가할 수도 있지만 이미 프래그먼트가 만들어져 있는 경우 밑 사진의 동그라미 친 버튼을 통해 쉽게 추가가 가능합니다. navigation 태그안에 각 프래그먼트가 그래프로 추가됩니다. 이때 id는 추후 bottomNavigationView 의 메뉴 아이디와 동일해야 네비게이션 기능이 이어져서 동작됩니다.
추가로 navigation 태그에 startDestinaion을 설정하여 처음 띄워질(이동할) 화면을 설정이 가능합니다.
또한 전 하나의 FrameLayout 안에 fragment를 탐색하는(이동) 용도로만 써서 오른쪽의 UI가 저렇게 겹치게만 되있습니다.
다른 값 전달 밑 특정 프래그먼트에서 다른 프래그먼트를 네비게이션하는 구조라면 밑과 같이 그려집니다. 네비게이션 장점중 하나가 이렇게 레이아웃 구조를 한눈에 보기 좋은 면도 있습니다.
4. 바텀네비게이션뷰의 menu xml 입니다. 해당 바텀네비게이션의 뷰를 누를 때 이동해할 프래그먼트와 id를 매칭시켜주어야합니다. (3번에서의 네비게이션 그래프의 fragment id와 매칭해줘야합니다.)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/countryFragment"
android:icon="@drawable/ic_statistics_white_24dp"
android:title="@string/menu_total_stat_title_text" />
<item
android:id="@+id/cityFragment"
android:icon="@drawable/ic_city_white_24dp"
android:title="@string/menu_local_stat_title_text" />
<item
android:id="@+id/updateFragment"
android:icon="@drawable/ic_update_white_24dp"
android:title="@string/menu_ready_title_text" />
</menu>
5. 마지막으로 액티비티에서 NavController로 세팅해주면 끝이 납니다. (initNavigation())
NavController란 NavController는 위에서 만든 내비게이션 그래프에 맞게 main_nav_host (호스트 네비게이션) 안이 구현되도록 도와주는 오브젝트입니다.
더 자세한 설명과 예제는 위 참고사이트나 아래 사이트를 참고합니다.
package com.mtjin.coronakorea.views
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController
import com.mtjin.coronakorea.R
import com.mtjin.coronakorea.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initBinding()
initNavigation()
}
private fun initNavigation() {
val navController = findNavController(R.id.main_nav_host)
binding.mainBottomNavigation.setupWithNavController(navController)
// 위와 같은 2번째 방법
// NavigationUI.setupWithNavController(
// main_bottom_navigation,
// findNavController(R.id.main_nav_host)
// )
}
private fun initBinding() {
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.lifecycleOwner = this
}
companion object {
const val TAG = "MainActivityTag"
}
}
6. 결과
보통 바텀바를 사용할 때 리스너를 사용해서 분기문으로 supportFragmentManager 를 사용해 replace 했었는데 그런 코드 없이 네비게이션을 통해 자동으로 연결됨을 볼 수 있습니다. 그리고 app:defaultNavHost="true" 로 인해 예시로 두번째 프래그먼트에서 뒤로가기 누를시 호스트화면(첫번째 프래그먼트)로 이동함을 볼 수 있습니다. 백스택 관리도 해주므로 매우 좋은 것 같습니다.
적용한 토이프로젝트 포스팅 내용은 간단한 네비게이션의 기능중 하나의 예이고 문서를 읽어보니 다양하고 좋은 기능이 많더라고요. 더 자세히 공부해보고 추후 프로젝트에 적용하면 좋을 것 같습니다. (바텀바뿐만 아니라 메뉴,툴바 등 적용, 값 전달, navigation을 통해 한눈에 앱 레이아웃 및 탐색 구조를 보기 좋고 관리하기 유용, Argument 값 전달, 애니메이션적용 등...)
위 프로젝트는 다음 저장소에서 보실 수 있습니다. :)
github.com/mtjin/CoronaKoreaReleaseVersion
[2021-01-23 업데이트]
액션바도 jetpack navigation이 적용이 가능한데 샘플 코드를 기록합니다. 주석을 보시면 기능이 이해가 가실거라고 생각합니다. 쉽게 액션바 및 뒤로가기 버튼이 자동 구현되니 유용할 수 있다 생각합니다. :)
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.setupActionBarWithNavController
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupActionBarWithNavController(findNavController(R.id.navHostFragment)) //액션바 뒤로가기 버튼 생김
}
override fun onSupportNavigateUp(): Boolean { //액션바 뒤로가기 클릭 시 동작
val navController = findNavController(R.id.navHostFragment)
return navController.navigateUp() || super.onSupportNavigateUp() //
}
}
이 코드의 링크는 github.com/mtjin/to-do-android-app 입니다.
댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!
'안드로이드 > 코틀린 & 아키텍처 & Recent' 카테고리의 다른 글
[코틀린] Jsoup 파싱 라이브러리 사용 기록 (0) | 2020.05.21 |
---|---|
[코틀린] Base 코드 관련 정리 (feat. BaseActivity, BaseFragment) (0) | 2020.05.08 |
[안드로이드] 코틀린 원형차트 예제 (feat. MPAAndroidChart 라이브러리) (0) | 2020.04.28 |
[안드로이드] 코틀린 list 를 자바의 vararg 로 받을 수 있게하는 방법 (kotlin list to vararg) (0) | 2020.04.28 |
[안드로이드] DI(Dependency Injection) 개념 및 KOIN 참고할 사이 (0) | 2020.04.15 |