[안드로이드] Navigation 과 BottomNavigationView 사용하기

이상욱·2022년 12월 22일
0

안드로이드

목록 보기
9/17
post-thumbnail

✅ Jetpack Navigation

1. build.gradle(:app)에 라이브러리를 추가합니다.

def nav_version = "2.5.3"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

2. Activity 1개와 Fragment2개를 준비합니다.

3. res폴더 아래에 nav_graph.xml파일을 만듭니다.

nav_graph.xml파일에 디자인탭 왼쪽 상단에 New Destination아이콘을 눌러서 프래그먼트 두개를 추가해줍니다. 그리고 firstFragment에서 클릭을 유지한채로 secondFragment로 연결하면 프래그먼트 간의 액션이 생깁니다.
그리고 startDestination속성에 처음으로 시작할 프래그먼트를 설정해줍니다.

4. 액티비티 레이아웃 파일에 FragmentContainerView를 만듭니다.

name을 "androidx.navigation.fragment.NavHostFragment"로 지정해줍니다.

app:navGraph 속성은 NavHostFragment를 탐색 그래프와 연결합니다. 탐색 그래프는 사용자가 이동할 수 있는 이 NavHostFragment의 모든 대상을 지정합니다.

app:defaultNavHost="true" 속성을 사용하면 NavHostFragment가 시스템 뒤로 버튼을 가로챕니다. 하나의 NavHost만 기본값으로 지정할 수 있습니다. 동일한 레이아웃에 여러 호스트가 있다면(예: 창이 2개인 레이아웃) 한 호스트만 기본 NavHost로 지정해야 합니다.

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_second_activity"
        app:navGraph="@navigation/nav_graph"
        />

네비게이션 설정이 끝났습니다. 아까 firstFragment에서 secondFragment로 연결한 액션을 실행시켜보겠습니다.

findNavContoller()에서 navigate를 호출하고 아까 연결한 액션의 아이디를 설정해주면 됩니다.

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        Log.d(TAG, "FirstFragment onViewCreated: ")
        binding.btnNextFragment.setOnClickListener {
            findNavController().navigate(R.id.action_firstFragment_to_secondFragment)
        }
    }

✅BottomNavigationView

1. 메뉴 만들기

res폴더 아래에 Menu를 만들어 줍니다. 여기서 중요한 점은 item들의 id가 위의 nav_graph에서 프래그먼트 id와 동일해야 합니다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="fragmentFirst"
        android:icon="@drawable/ic_one_24"
        android:title="첫번째 프래그먼트" />

    <item
        android:id="fragmentSecond"
        android:icon="@drawable/ic_two_24"
        android:title="두번째 프래그먼트" />
</menu>

2. activity_main.xml에서 BottomNavigationView를 작성해줍니다.

menu속성에 이미 정의한 bottom_nav_menu를 지정해줍니다.

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:menu="@menu/bottom_nav_menu" />

3. Activity에서 네비게이션과 바텀네비게이션을 연결해줍니다.

val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
        val navController = navHostFragment.navController
        NavigationUI.setupWithNavController(binding.bottomNavigationView, navController)

✅ Safe-args

Jetpack Navigation을 사용할 때 값을 넘겨줄 때 Safe-args로 값을 넘겨 줄 수 있습니다.

build.gradle(:app)

plugins{
	...
	id 'androidx.navigation.safeargs.kotlin'
}

build.gradle(Module)

모듈 단위의 build.gradle에 플러그인을 추가해 줄 때 네비게이션 라이브러리 버전을 nav_version에 넣어 줍니다.

plugins{
	...
	 id 'androidx.navigation.safeargs.kotlin' version 'nav_version' apply false
}

값을 받고자 하는 프래그먼트를 눌러 디자인탭 우측에 Arguments 옆 +버튼을 눌러줍니다.


여기서 받고자 하는 변수명과 타입을 설정해줍니다.

그리고 값을 보내는 프래그먼트에서 받는 프래그먼트에 action으로 연결해줍니다.

보내는 프래그먼트

보내는 프래그먼트에서는 Directions를 통해 설정해준 action을 찾아 보낼 값을 파라미터로 보냅니다. 그리고 navigate를 통해 action을 넘겨줍니다.

val action = SearchFragmentDirections.actionSearchFragmentToBookFragment(보낼 값)
            findNavController().navigate(action)

받는 프래그먼트

받는 프래그먼트에서는 args by navArgs<>() 형태로 args를 초기화하고 args에서 이전에 설정한 변수명으로 값을 받아옵니다.

 private val args by navArgs<BookFragmentArgs>()
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val book = args.book
        
    }
profile
항상 배우고 성장하는 안드로이드 개발자

0개의 댓글