일단 앱을 만들기 시작했으니 기본적으로 Main Activity의 레이아웃을 구성하려고 한다.
메인 액티비티는 단순하게 Fragment를 띄울 FramLayout하나와 Bottom Navigation Bar 한개로만 구성하였다.

프레그먼트를 띄울 Framlayout은 정말 필수적인 설정 외에는 하지 않았다.
<FrameLayout
android:id="@+id/main_frame"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_layout"
android:orientation="vertical">
</FrameLayout>
그러면 이제 남은것은 Bottom Navigation Bar이다
우선 네비게이션 바를 사용하기위해 의존성을 추가해줬다.
def nav_version = "2.5.3"
/*네비게이션바 의존성*/
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
글을 작성하는 5월 8일기준 23년 2월22일 업데이트된 2.5.3버전이 최신버전이다.
최신버전 확인은 아래 링크에서 하면 된다.
Navigation | Android 개발자 | Android Developers
컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Navigation Navigation은 Android 애플리케이션 내에서 '대상' 사이를 탐색하는 프레임워크로, 대상이 Fragment, Activity
developer.android.com
이후 다시 xml파일로 돌아와서 네비게이션 바를 추가해주자
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:menu="@menu/bottom_navbar"
app:itemIconSize="35dp"
app:labelVisibilityMode="unlabeled" <!-- 메뉴xml에서 설정한 title의 노출 여부 , 디폴트는 able -->
android:background="@color/white"
/>
메뉴 아이템의 아이콘들은 구글 폰트에서 기본 제공하는 아이콘들을 가져와서 사용하였다
Material Symbols and Icons - Google Fonts
Material Symbols are our newest icons consolidating over 2,500 glyphs in a single font file with a wide range of design variants.
fonts.google.com
이제 레이아웃이 끝났으니 메인 액티비티 클래스의 코드를 작성해 주도록 하자
우선 뷰 바인딩을 사용해 주었다. 뷰 바인딩을 사용하면 장점이 여러가지가 있겠지만 무엇보다 매번 위젯 등록을 안해줘도 되기 때문에 굉장히 편해진다는것이 가장 큰 강점인것 같다.
// 전역 변수로 바인딩 객체 선언
private var mBinding: ActivityMainBinding? = null
// 매번 null 체크를 할 필요 없이 편의성을 위해 바인딩 변수 재 선언
private val binding get() = mBinding!!
그리고 네비게이션 바에서 메뉴를 누를시 그에 해당하는 프레그먼트로 이동하도록 setFrag()라는 함수를 만들었다.
private fun setFrag(fragNum: Int) {
val ft = supportFragmentManager.beginTransaction()
when(fragNum){
0 -> {
ft.replace(R.id.main_frame, RecycleView_Frag()).commit()
}
1-> {
ft.add(R.id.main_frame, Add_schedule_fragment()).commit()
}
2->{
}
}
}
메뉴 아이템은 총 3개가 있지만 나머지 하나는 맨 마지막에 구현할 생각이기 때문에 따로 만들어두지 않았다.
자 이제 뷰 바인딩도 설정해 주었고, 함수도 만들어두었으니 이제 onCreate()에서 이용해주기만 하면된다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setFrag(0)
binding.navBar.run{setOnNavigationItemSelectedListener {
when(it.itemId){
R.id.account ->{
setFrag(0)
true
}
R.id.add ->{
setFrag(1)
true
}
else -> false
}
}}
}
뷰 바인딩객체와 메인 액티비티를 연결시켜준뒤 RecycleView_Frag 프레그먼트가 제일 먼저 노출되는 화면이기 때문에 setFrag(0)으로 맨 처음에 노출되게 설정해 주었다.
글을 작성하면서 다시 코드를 들여다보니 setOnNavigationItemSelectedListener{}는 이제 사용이 권장되지 않는 메서드라고 한다. 현재 권장되는 메소드는 setOnItemSelectedListener 이라고 하는데 사실 목적에 따라서 사용하는것이 달라진다.
| 메소드명 | setOnNavigationItemSelectedListener | setOnItemSelectedListener |
| Callback시점 | 메뉴 아이템이 선택될 때마다 즉각적으로 Callback이 실행 | 선택된 아이템이 바뀌는 순간에만 Callback이 실행 |
즉 setOnNavigationItemSelectedListener는 선택된 메뉴 아이템에 대한 즉각적인 처리가 필요할 때 사용하고, setOnItemSelectedListener는 선택된 아이템이 변경될 때만 처리가 필요할 때 사용된다고 생각하면 되겠다.
추가적으로 setOnItemSelectedListener는 API 28이상 부터 동작한다고 하니 유의하자
아래는 메인 액티비티 클래스와 레이아웃 전체 코드이다.
class MainActivity : AppCompatActivity() {
// 전역 변수로 바인딩 객체 선언
private var mBinding: ActivityMainBinding? = null
// 매번 null 체크를 할 필요 없이 편의성을 위해 바인딩 변수 재 선언
private val binding get() = mBinding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setFrag(0)
binding.navBar.run{setOnNavigationItemSelectedListener {
when(it.itemId){
R.id.account ->{
setFrag(0)
true
}
R.id.add ->{
setFrag(1)
true
}
else -> false
}
}}
}
private fun setFrag(fragNum: Int) {
val ft = supportFragmentManager.beginTransaction()
when(fragNum){
0 -> {
ft.replace(R.id.main_frame, RecycleView_Frag()).commit()
}
1-> {
ft.add(R.id.main_frame, Add_schedule_fragment()).commit()
}
2->{
}
}
}
}
<?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">
<FrameLayout
android:id="@+id/main_frame"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_layout"
android:orientation="vertical">
</FrameLayout>
<LinearLayout
android:id="@+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="horizontal"
>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:menu="@menu/bottom_navbar"
app:itemIconSize="35dp"
app:labelVisibilityMode="unlabeled"
android:background="@color/white"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>'Android > [Kotlin]' 카테고리의 다른 글
| [Android][Kotlin] Schedule App - Fragment(2) (0) | 2023.05.12 |
|---|---|
| [Android][Kotlin] Schedule App - Fragment(1) (2) | 2023.05.09 |
| [Android][Kotlin] Schedule app만들기-(0) (0) | 2023.05.08 |
| [Kotlin] 카메라 예제 (0) | 2023.04.01 |