-
[Android/Kotlin] Jetpack Bottom Navigation Bar안드로이드 개발 2020. 8. 17. 16:20
미리보기
Jetpack Navigation은 UI 전환을 쉽게 구현할 수 있도록 도와준다. Navigation을 자동으로 연결해주어 불필요한 코드 작성을 줄이고, 유지보수에도 용이하다. 또한 Back Stack 관리 등 여러 장점으로 인하여 사용하게 되었다.
Jetpack의 장점
- 프래그먼트 트랜잭션 처리.
- 기본적으로 '위로'와 '뒤로' 작업을 올바르게 처리.
- 애니메이션과 전환에 표준화된 리소스 제공.
- 딥 링크 구현 및 처리.
- 최소한의 추가 작업으로 탐색 UI 패턴(예: 탐색 창, 하단 탐색) 포함.
- Safe Args - 대상 사이에서 데이터를 탐색하고 전달할 때 유형 안정성을 제공하는 그래프 플러그인입니다.
- ViewModel 지원 - 탐색 그래프에 대한 ViewModel을 확인해 그래프 대상 사이에 UI 관련 데이터를 공유합니다.
※ Android studio 3.3 이상부터 사용이 가능하다.
관련 자료
↓ Google material에서 제공하는 Bottom Navigation Bar 관련 자료
https://material.io/develop/android/components/bottom-navigation
↓ Android에서 제공하는 Jetpack 관련 자료
https://developer.android.com/jetpack?hl=ko
↓ Android에서 제공하는 Jetpack Navigation 관련 자료
https://developer.android.com/guide/navigation
01. build.gradle 의존성 추가
android {} 내부에 android.dataBinding을 추가해준다.
[Gradle Scripts] - [build.gradle(Module: app)]
android.dataBinding { enabled = true }
fragment간에 값을 전달하지 않고, 전환만 할 경우 아래 Dependency만 추가해주면 된다. 전달해야 할 값이 있다면 다른 Dependency도 추가해줘야 한다.
[Gradle Scripts] - [build.gradle(Module: app)]
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2' implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
02. Fragment 생성
원하는 navigaion 갯수만큼 Fragment를 생성해준다. Google에서는 3개 이상을 사용할 것을 권장한다.
03. Main XML (Bottom Navigaion Bar가 들어갈 Activity의 XML)
databinding을 위해 layout 태그로 감싸준다.
- fragment : android:name="androidx.navigation.fragment.NavHostFragment"
NavHost(탐색 그래프에서 대상을 표시하는 빈 컨테이너) 역할을 한다.
- fragment : app:defaultNavHost="true"
뒤로 가기 버튼을 누르면 NavHostFragment(@navigation/navi_graph에서 app:startDestination으로 설정)로 돌아온다. false가 기본값으로 뒤로가기 버튼을 누르면 바로 앱이 종료된다.
- fragment : app:navGraph="@navigation/navi_graph"
NavHostFragment와 내비게이션 그래프를 연결시킨다. (05에서 생성)
- BottomNavigationView : app:menu="@menu/navi_menu"
BottomNavigationView와 menu를 연결시킨다.
- BottomNavigationView : app:labelVisibilityMode="unlabeled"아이콘 밑의 lable을 비활성화 시킨다. (menu의 title에서 지정해준다.)
- BottomNavigationView : app:itemIconTint="@drawable/navi_selector"아이콘 색상을 지정해주는 옵션이다. '@color/mainBlue'나 '#000000' 등 색상으로 지정해주면 전체 색상이 바뀌고, 눌렸을 때와 눌리지 않았을 때 색상을 지정해주고 싶을 경우 drawable 폴더에 selector를 만들어준다. (04에서 생성)
- BottomNavigationView : app:layout_behavior="tech.thdev.app.view.BottomNavigationBehavior"스크롤시 하단으로 숨기게 하는 라이브러리이다.
[res] - [layout] - act_main.xml
<?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"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/fl_container" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@id/navi" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <fragment android:id="@+id/navi_host" android:layout_width="match_parent" android:layout_height="match_parent" android:name="androidx.navigation.fragment.NavHostFragment" app:defaultNavHost="true" app:navGraph="@navigation/navi_graph" /> </FrameLayout> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/navi" android:layout_width="match_parent" android:layout_height="@dimen/naviH" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/fl_container" android:background="@color/white" app:menu="@menu/navi_menu" app:labelVisibilityMode="unlabeled" app:itemIconTint="@drawable/navi_selector" app:layout_behavior="tech.thdev.app.view.BottomNavigationBehavior" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
04. seletor 사용하여 아이콘 색상 변경 (itemIconTint)
아이콘이 선택됐을 때와 선택되지 않았을 때 원하는 색상을 지정해주기 위해 selector를 만들어서 BottomNavigationView에 적용시킨다.
- item : android:color="@color/mainBlue"
state_checked=true인 항목이 Navigation에서 선택된 상태이다. @color/에서 원하는 색상을 불러오거나 '#000000'과 같이 hex 색상을 직접 입력해줄 수 있다.
[res]- [drawable] - navi_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/mainBlue" android:state_checked="true"/> <item android:color="@color/mainGray" android:state_checked="false"/> </selector>
05. 내비게이션 그래프 생성
내비게이션 그래프는 모든 탐색 관련 정보가 하나의 중심 위치에 모여 있는 XML 리소스이다. 여기에는 대상이라고 부르는 앱 내의 모든 개별적 콘텐츠 영역과 사용자가 앱에서 갈 수 있는 모든 이용 가능한 경로가 포함된다.
- navigation app:startDestination="@id/fragHome"
기본 화면(처음 뜨는 화면, 돌아오는 화면)을 지정해줍니다. 원하는 fragment 아이디를 써주면 된다.
- fragment : android:id="@+id/fragHome"
이 아이디는 이후에 만들 menu의 item 아이디와 동일해야 한다.
- fragment : android:name="com.app0.simforpay.HomeFrag"java 폴더 내의 kotlin 파일의 이름을 넣어준다. com.app0.simforpay는 자신의 프로젝트명이고, HomeFrag는 kotlin 파일명이다.
- fragment : tools:layout="@layout/frag_home"각 fragment에 XML 파일을 연결시켜 layout을 지정해준다.
[res] - [navigation] - navi_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" app:startDestination="@id/fragHome"> <fragment android:id="@+id/fragHome" android:name="com.app0.simforpay.HomeFrag" tools:layout="@layout/frag_home" /> <fragment android:id="@+id/fragCalendar" android:name="com.app0.simforpay.CalendarFrag" tools:layout="@layout/frag_calendar" /> <fragment android:id="@+id/fragContract" android:name="com.app0.simforpay.ContractFrag" tools:layout="@layout/frag_contract" /> <fragment android:id="@+id/fragFriends" android:name="com.app0.simforpay.FriendsFrag" tools:layout="@layout/frag_friends" /> <fragment android:id="@+id/fragSetting" android:name="com.app0.simforpay.SettingFrag" tools:layout="@layout/frag_setting" /> </navigation>
06. menu 생성
- item : android:id="@+id/fragHome"
전에 만든 내비게이션 그래프의 fragment 아이디와 동일해야 한다.
- item : android:icon="@drawable/ic_tab_home"
원하는 아이콘 파일을 불러온다.
- item : android:title="홈"
아이콘 밑에 표시될 레이블을 지정해준다.
[res] - [menu] - menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/fragHome" android:icon="@drawable/ic_tab_home" android:title="홈" /> <item android:id="@+id/fragCalendar" android:icon="@drawable/ic_tab_calendar" android:title="달력" /> <item android:id="@+id/fragContract" android:icon="@drawable/ic_add" android:title="작성" /> <item android:id="@+id/fragFriends" android:icon="@drawable/ic_tab_friends" android:title="친구" /> <item android:id="@+id/fragSetting" android:icon="@drawable/ic_tab_setting" android:title="설정" /> </menu>
07. MainAct 작성
act_main과 연결된 MainAct.kt 파일에 코틀린 코드를 작성한다.
※private lateinit var binding: ActMainBinding 빠트리지 않도록 주의해야 한다.
- initNavigation() : NavigationUI.setupWithNavController(①, findNavController(R.id.②))
① act_main.xml의 BottomNavigationView 아이디
② act_main.xml의 fragment 아이디
- initBinding() : binding = DataBindingUtil.setContentView(this, R.layout.③)
③ MainAct와 연결 할 XML 파일 : act_main.xml
[java] - MainAct.kt
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.databinding.DataBindingUtil import androidx.navigation.findNavController import androidx.navigation.ui.NavigationUI import com.app0.simforpay.databinding.ActMainBinding import kotlinx.android.synthetic.main.act_main.* class MainAct : AppCompatActivity() { private lateinit var binding: ActMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) initBinding() initNavigation() } private fun initNavigation() { NavigationUI.setupWithNavController(navi, findNavController(R.id.navi_host)) } private fun initBinding() { binding = DataBindingUtil.setContentView(this, R.layout.act_main) binding.lifecycleOwner = this } }
완성
본 작성자는 안드로이드 개발을 공부하고 있는 학생으로 피드백 및 질문을 환영합니다. 그러나 무단복제 및 배포는 정중하게 사양하고 있으며, 참고 사이트로 링크를 남기실 때는 동의를 구해주시기 바랍니다.
반응형'안드로이드 개발' 카테고리의 다른 글