chacha's

🎹 Bottom Navigation 사용하기 본문

Android/My Library

🎹 Bottom Navigation 사용하기

Cha_Cha 2021. 5. 30. 00:22

목차

     Android Architecture Components Advanced Navigation Sample - Github
     BottomNavigationView - Getting Started With Navigation Component - Youtube
     Null NavHostFragment/NavController with FragmentContainerView - stack overflow
     Using Bottom Navigation - material.io
     Integrate the Navigation component - Docs
     위의 내용을 참고하여 작성하였습니다.

     

     BottomNavigationView

    🚨 UI 주의사항

    Bottom Navigation UI를 사용할 때 주의해야 할 사항이 있습니다. 아래의 내용보다 더 자세한 가이드는 material.io에서 확인할 수 있습니다.

    • Navigation을 구성하는 탭은 3개보다 적으면 안 됩니다. 이 경우 Tabs을 사용하는 것을 권장합니다.
    • Navigation을 구성하는 탭은 5개를 초과할 수 없습니다.

    • 텍스트의 길이를 너무 길게 하면 안 됩니다.
    • 텍스트의 크기를 기본 값보다 작게 하면 안 됩니다.

    • 다양한 색상의 아이콘과 텍스트를 사용하면 안 됩니다.
    • Navigation을 구성하는 탭들은 고정된 위치를 가져야 합니다. 스크롤되거나 움직이면 안 됩니다.

     

    💾 사용 방법

    BottomNavigationView를 Navigation Component, Data Binding과 함께 사용하는 방법입니다. 

    Data Binding 게시글 참고하기
    Navigation 게시글 참고하기

    1. Dedendency 추가하기 ( build.gradle - app )

    android {
        ...
        buildFeatures {
            dataBinding true
        }
    }
        // navigation
        implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
        implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
        
        // material design
        implementation 'com.google.android.material:material:1.3.0'

    2. Menu resource 파일 생성하기

    Menu resource 파일은 BottomNavigationView에 보일 탭들을 선언해놓는 파일입니다. 이때, 탭의 개수는 3개 이상 5개 이하여야 합니다.

    3. 각각의 탭을 위한 Fragment 생성하기

    HomeFragment class 파일
    fragment_home.xml 파일

    4. Navigation resource 파일 생성하기

    각각의 탭에 대하여 모두 navigation resource 파일을 생성해줘도 되고 nav_graph 파일 내에 fragment 키워드로 각자 선언해도 됩니다. 아래에서는 include 키워드를 이용하여 navigation resouce 파일을 합쳐서 사용하는 방법으로 구현하였습니다.

    이때, 각 탭에 대한 navigation res 파일의 android:id과 menu res 파일의 각 item의 android:id가 동일한 이름으로 선언되어 있어야 합니다. 이를 동일하게 설정하지 않을 경우, java.lang.NullPointerException: null cannot be cast to non-null type androidx.navigation.fragment.NavHostFragment과 같은 에러를 만날 수 있습니다. ( 참고 - stackoverflow )

    nav_graph navigation resouce 파일 생성
    home navigation resource 파일 생성

    5. XML resource 파일에 BottomNavigationView 추가하기

    아래(    박스 부분)와 같이 BottomNavigationView의 속성에 menu res를 연결해주면 됩니다. 또한 Navgiation Component의 fragment를 교체할 부분으로 FragmentContainerView를 선언해주어야 합니다.

        박스 부분에서 android:name 속성을 반드시 선언해주어야 합니다. 이를 선언하지 않을 경우,  java.lang.NullPointerException: null cannot be cast to non-null type androidx.navigation.fragment.NavHostFragment과 같은 에러를 만날 수 있습니다. ( 참고 - stack overflow )

    6. MainActivity에서 Fragment와 BottomNavigationView 연결해주기

    class MainActivity : AppCompatActivity() {
        private lateinit var binding: ActivityMainBinding
        
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            @Suppress
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
            binding.lifecycleOwner = this
    
            val navHostFragment = supportFragmentManager.findFragmentById(
                R.id.nav_host_fragment
            ) as NavHostFragment
            val navController = navHostFragment.navController
    
            setSupportActionBar(binding.toolbar)
            NavigationUI.setupActionBarWithNavController(this, navController)
    
            binding.bottomNavigation.setupWithNavController(navController)
        }
    }

    위의 코드처럼 작성할 경우 아래의 GIF 중 왼쪽과 같이 Bottom Navigation으로 다른 Fragment로 이동했을 때, Back button이 나타나는 문제가 발생합니다. 이를 오른쪽과 같이 고치기 위해서는 AppBarConfiguration을 추가해주어야 합니다.

    왼쪽 - back button이 나타남 / 오른쪽 - back button이 안 나타남

    ▼ AppBarConfiguration을 추가한 코드 ( 위의 오른쪽 GIF처럼 동작 )

    class MainActivity : AppCompatActivity() {
        private lateinit var binding: ActivityMainBinding
        private lateinit var appBarConfiguration: AppBarConfiguration
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            @Suppress
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
            binding.lifecycleOwner = this
    
            val navHostFragment = supportFragmentManager.findFragmentById(
                R.id.nav_host_fragment
            ) as NavHostFragment
            val navController = navHostFragment.navController
    
            appBarConfiguration = AppBarConfiguration(
                setOf(R.id.home, R.id.calendar)
            )
            setSupportActionBar(binding.toolbar)
            NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
    
            binding.bottomNavigation.setupWithNavController(navController)
        }
    }

    🎨 BottomNavigationView의 Icon과 Text 색상 바꾸기

    Bottom navigation bar 의 색상 설정

    위의 그림에서 알 수 있듯이 각 탭의 색상은 선택되었을 때는 On Primary 색상의 100% 투명도를 가지고, 선택되지 않았을 때는 76%의 투명도를 가집니다. 이와 다르게 탭이 선택되었을 때와 선택되지 않았을 때 색상을 다르게 하고 싶다면 color resource 파일을 이용하면 됩니다. 

    selector_bottom_navigation.xml

    selector를 이용한 xml 파일을 생성한 후에 이를 BottomNavigationView의 속성( itemIconTint, itemTextColor )에 연결해주면 됩니다.

    END

    Comments