[Kotlin] BottomNavigationView 구현하기

han·2021년 8월 11일
0

BottomNavigationView이 필요해서 만들어보려고 한다.
그래서 검색하던 도중 BottomNavigationView을 만들 때 구글에서 정해준 가이드라인이 있다고 한다. 무엇인지 알아보자.

BottomNavigationView 가이드라인

참고 : https://material.io/components/bottom-navigation

사이트를 보면 자세하게 설명이 나와있는데, 정리하자면

  • 1줄을 넘어가는 텍스트 사용하지 말 것

  • 바텀 메뉴 아이템의 색상을 단색이 아닌 여러 색을 처리하지 않는 것을 권장

  • 바텀 메뉴 누를 경우 ViewPager 상에 swipe 에니메이션 처리하지 말 것

  • 스크롤이 발생할 경우 바텀 메뉴는 숨김 처리하며 다시 위로 올라오면 노출할 것

  • 가이드상 바텀 메뉴가 3개 이상에서 사용하여 할 것

  • 바텀 메뉴가 4~5개일 경우는 이미지로만 노출할 것

등이 있는데, 처음부터 이러한 가이드가 있다는 걸 알고 개발에 들어가면 후에 번거로운일이 줄어들 것 같다.

그러면 BottomNavigationView 구현 방법에 대해서 알아보자.

1. BottomNavigationView 구현 방법

  1. menu.xml 만들기

  2. activity_main.xml 만들기

    여기서 개발을 하면서 경험한건데 바텀 메뉴가 3개일때는 아이콘이랑 텍스트가 다나오는데 4개부터는 가이드처럼 아이콘이미지만 나온다.

    해서 이런경우 아이콘이랑 이미지 둘다 나오게 하려면 코드를 추가시켜줘야한다.

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bnv_main"
        app:menu="@menu/navi_menu"
        android:layout_width="0dp"
        android:background="#FFFFFF"
        android:layout_height="?attr/actionBarSize"
        app:labelVisibilityMode="labeled" // 이 부분 추가
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

  1. Fragment추가해서 분할할 화면 만들기.

홈프래그먼트.xml

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private val fl: FrameLayout by lazy {
        findViewById(R.id.fl_con)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val bnv_main = findViewById<BottomNavigationView>(R.id.bnv_main)

        //supportFragmentManager.beginTransaction().add(R.id.fl_con, NaviHomeFragment()).commit()

        bnv_main.setOnItemSelectedListener { item ->
            changeFragment(
                when (item.itemId) {
                    R.id.first -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv1)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv1)
                        NaviHomeFragment()
                        // Respond to navigation item 1 click
                    }
                    R.id.first2 -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv2)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv2)
                        NaviAttendanceFragment()
                        // Respond to navigation item 2 click
                    }
                    R.id.first3 -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv2)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv2)
                        NaviInfoFragment()
                        // Respond to navigation item 3 click
                    }
                    else -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv1)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv1)
                        NaviCertificateFragment()
                    }
                }
            )
            true
        }
        bnv_main.selectedItemId = R.id.first
    }

    private fun changeFragment(fragment: Fragment) {
        supportFragmentManager
            .beginTransaction()
            .replace(R.id.fl_con, fragment)
            .commit()
    }
}

여기서 코드를 간략히 설명하자면 BottomNavigationView를 사용해서 4개의 Fragment를 이용해 화면전환을 하는 코드이다.

추가로 앱을 처음 열때 원하는 메뉴를 지정하고 싶을때는 밑의 코드를 추가해준다.

bnv_main.selectedItemId = R.id.first

구현결과

추가적인 이슈

(1) BottomNavigationView의 ItemselectedListener

위 사진대로 지금까지 사용하던 리스너가 deprecated되어 대안이 필요하다. 해서 사용한 것이

NavigationBarView.OnItemSelectedListener { item ->
    when(item.itemId) {
        R.id.item1 -> {
            // Respond to navigation item 1 click
            true
        }
        R.id.item2 -> {
            // Respond to navigation item 2 click
            true
        }
        else -> false
    }
}

이다.

(2) 바텀네비뷰에서 각 메뉴들을 클릭했을때 색깔을 다르게 만든다면.

2. 메뉴를 선택/비선택 상태의 color파일 만들기 ( StateListDrawable ( 상태 드로어블 ) 사용 )

color_bnv1.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/design_default_color_primary" android:state_checked="true" />
    <!-- @color/colorTab1 = #006064 //define this in your res/values/color.xml or change the color directly here -->
    <item android:color="@android:color/darker_gray" android:state_checked="false" />
</selector>

MainActivity.kt

        bnv_main.setOnItemSelectedListener { item ->
            changeFragment(
                when (item.itemId) {
                    R.id.first -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv1)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv1)
                        NaviHomeFragment()
                        // Respond to navigation item 1 click
                    }
                    R.id.first2 -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv2)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv2)
                        NaviAttendanceFragment()
                        // Respond to navigation item 2 click
                    }
                    R.id.first3 -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv3)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv3)
                        NaviInfoFragment()
                        // Respond to navigation item 3 click
                    }
                    else -> {
                        bnv_main.itemIconTintList = ContextCompat.getColorStateList(this, R.color.color_bnv4)
                        bnv_main.itemTextColor = ContextCompat.getColorStateList(this, R.color.color_bnv4)
                        NaviCertificateFragment()
                    }
                }
            )
            true
        }
        bnv_main.selectedItemId = R.id.first

구현결과

참고 : https://acomputerengineer.com/2020/01/13/different-colors-for-selected-tab-in-bottomnavigationview-in-android-kotlinprogrammatically/

profile
개인 공부 및 기록겸 벨로그 시작

0개의 댓글