나만 보는 일기장

[Navigation Component] Navigation Component + Bottom Navigation View 사용하기 본문

개발/Android

[Navigation Component] Navigation Component + Bottom Navigation View 사용하기

Patrick0422 2021. 10. 31. 16:23

순서

  1. BottomNavigationView 추가
  2. menu 파일 생성
  3. menu 적용
  4. Navigation Component와 Bottom Navigation View 연결

 

 

Navigation Component 사용법

0. 프로젝트 설정 앱 단위 Gradle plugins { ... id 'androidx.navigation.safeargs.kotlin' } ... dependencies { ... def nav_version = "2.4.0-alpha06" // Kotlin implementation "androidx.navigation:naviga..

patrick-dev.tistory.com

Navigation Component 설정은 위 글에서 3번까지 참고하면 된다.

 

 

1. BottomNavigationView 추가

BottomNavigationView를 만들어주자~

2. menu 파일 생성

res 우클릭 - new - Android Resource File - Resource type을 Menu로 바꾼 뒤 이름을 설정하고 만들어준다.

 

menu 파일은 BottomNavigationView에 나타나는 아이템들을 설정하는 역할을 한다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/homeFragment"
        android:title="@string/home"
        android:icon="@drawable/ic_home"/>
    <item
        android:id="@+id/secondFragment"
        android:title="@string/menu"
        android:icon="@drawable/ic_menu"/>
    <item
        android:id="@+id/thirdFragment"
        android:title="@string/notification"
        android:icon="@drawable/ic_notifications"/>
</menu>

각각의 항목들은 <item> 태그를 사용해서 나타내는데, 그 안에 들어가는 속성으로는 id, title, icon 등이 있다.

여기서 id는 nav_graph에 나타나는 프래그먼트의 이름과 똑같이 설정해주어야 한다.

title 태그는 BottomNavigationView에 나타나는 메뉴의 이름이고, icon은 말 그대로 아이콘을 설정한다.

 

3. menu 적용

BottomNavigationView의 app:menu 속성에서 방금 만든 menu파일을 지정해주면 쨘 하고 생긴다..

 

참고)

이렇게 글자를 없애고 싶다면

app:labelVisibilityMode="unlabeled"

위 라인을 추가해주자.

 

4. Navigation Component와 Bottom Navigation View 연결

가장 중요한 연결을 해보도록 하자. 순서는 대충 다음과 같다.

1. 레이아웃의 NavHostFragment에서 NavController을 받아온다.

2. AppBarConfiguration을 만든다

3.

4. setupActionBarWithNavController() 함수를 호출한다.

5. onSupportNavigateUp() 함수를 오버라이드 한다.

 

1. 레이아웃의 NavHostFragment에서 NavController을 받아온다.

navController = binding.fragmentContainerView.findNavController()

처음엔 위와 같은 코드를 써봤는데, NavController을 찾을 수 없다는 예외가 발생했다.

 

IllegalStateException: Link does not have a NavController set

I'm using Android Navigation Component for Navigation. I have a LoginFragment which has a button to transition to SignUpFragment. On clicking the button I'm getting this error. java.lang.

stackoverflow.com

위 글을 참고해보니, NavController는 supportFragmentManager이라는 녀석을 사용해야 한다고 나와있다.

 

supportFragmentManager을 사용해 받아오는 코드는 다음과 같다.

val navHostFragment = supportFragmentManager.findFragmentById(NavHostFragment의 아이디) as NavHostFragment
navController = navHostFragment.navController

2. AppBarConfiguration을 만든다

val appBarConfiguration = AppBarConfiguration(
    setOf(
        R.id.homeFragment,
        R.id.secondFragment,
        R.id.thirdFragment
    )
)

3. bottomNavigationView의 setupWithNavController() 함수를 호출한다.

binding.bottomNavigationView.setupWithNavController(navController)

4. setupActionBarWithNavController() 함수를 호출한다.

setupActionBarWithNavController(navController, appBarConfiguration)

5. onSupportNavigateUp() 함수를 오버라이드 한다.

override fun onNavigateUp(): Boolean = navController.navigateUp() || super.onNavigateUp()

최종 코드

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.navcomp_bottomnav.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
        navController = navHostFragment.navController

        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.homeFragment,
                R.id.secondFragment,
                R.id.thirdFragment
            )
        )

        binding.bottomNavigationView.setupWithNavController(navController)
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

        override fun onNavigateUp(): Boolean = navController.navigateUp() || super.onNavigateUp()
}
Comments