[Android] Jetpack의 Navigation 사용하기

헤헤·2022년 10월 29일

Android

목록 보기
2/3

Navigation은 Jetpack 라이브러리중 하나로 Fragment 간의 흐름을 설정할 수 있고, 눈으로도 바로 확인할 수 있기 때문에 유용하게 사용할 수 있습니다.


Navigation 은 아래 3개의 구성 요소로 이루어져있습니다.

  • Navigation Graph : 모든 Navigation 관련 정보가 하나의 중심 위치에 모여있는 XML 리소스 파일입니다. destination 이라고 부르는 앱 내의 모든 개별적 콘텐츠 영역과 사용자가 앱에서 갈 수 있는 모든 경로가 포함됩니다.

  • NavHost : Navigation Graph 에서 대상을 표시하는 빈 컨테이너 입니다. 대상 구성요소에는 프래그먼트 대상을 표시하는 기본 NavHost 의 구현인 NavHostFragment가 포함됩니다.

  • NavController : NavHost 에서 Navigation 을 관리하는 객체입니다. NavController 를 통해 콘텐츠를 전환할 수 있습니다.


1. 의존성 추가

Jetpack의 Navigation을 사용하기 위해서는, 먼저 app 레벨의 build.gradle에 의존성을 추가해줍니다.

dependencies {
	...

    // Navigation JetPack
    implementation "androidx.navigation:navigation-fragment-ktx:2.5.0"
    implementation "androidx.navigation:navigation-ui-ktx:2.5.0"
   	...
}

만약 Navigation 에서 제공하는 Safe Args 를 통해 대상 간 데이터를 전달하고 싶으면, 프로젝트 레벨의 build.gradle에 해당 classpath를 추가합니다.

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.5.0"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

그리고 app 레벨의 build.gradle 에도 Safe Args 의존성을 추가합니다.

plugins {
  id 'androidx.navigation.safeargs'
}

2. Navigation Graph 리소스 파일 생성하기

  • 먼저 Navigation Graph 리소스 파일을 저장하기 위해 navigation 이름으로 resource directory 를 만들어 줍니다.
  • 다음으로 Navigation Graph 리소스 파일(main_nav_graph.xml) 을 생성합니다.

3. Navigation Graph 구성하기

  • 이제 Fragment 간의 연결 관계를 설정해줍니다. 직전에 생성한 main_van_graph.xml 파일에 연결 할 Fragment를 추가해줍시다.
  • + 버튼을 클릭하여 원하는 Fragment 를 추가해줍니다.
  • 그러면 화면에서 위와 같이 추가된 Fragment 를 확인할 수 있습니다.
  • 다음으로 두 Fragment 간의 연결 관계를 설정하기 위해 시작 Fragment 의 오른쪽 동그라미를 도착 Fragment 에 끌어서 연결해줍니다.
  • 그러면 위와 같이 두 Fragment 간의 연결 관계가 설정됩니다.
  • main_nav_garph.xml 파일의 코드를 확인하면 action 태그가 추가된 것을 확인할 수 있습니다.

4. FragmentContainerView 생성하기

  • 이제 Fragment 를 담을 Container 를 만들어줍니다.
    화면 전환 시 Container 에 다른 Fragment 가 올라오면서 화면이 전환됩니다.
  • androidx.fragment.app.FragmentContainerView 태그로 컨테이너를 만들 수 있습니다.

activty_main.xml

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

    <data>

        <variable
            name="activity"
            type="com.jae464.placememo.MainActivity" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toTopOf="@id/bottomNavigationView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"

            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/main_nav_graph" />

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNavigationView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/nav_host_fragment"
            app:menu="@menu/bottom_navigation_menu" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
  • android:name="androidx.navigation.fragment.NavHostFragment" 로 이름을 지정해줍니다.
  • app:navGraph 속성에 전에 만들었던 navigation 리소스 파일 을 넣어줍니다.
  • app:defaultNavHost="true" 를 지정하면, NavHostFragment 가 시스템 뒤로 가기 버튼을 가로챕니다. 하나의 NavHost 만 기본값으로 지정할 수 있습니다.

4. Activity 에서 Navigation 사용하기

  • Activity 에서 NavController 를 통해 Navigation 을 조작할 수 있습니다.
    Activity 가 만들어졌을때, NavController 를 가져옵니다.
@AndroidEntryPoint
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)
        binding.activity = this

		// NavController 가져오기
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        navController = navHostFragment.findNavController()
    }

}

5. NavController 로 화면 전환하기

  • HomeFragment 에서 업로드 버튼을 누르면 PostFragment로 이동하도록 해봅시다.
@AndroidEntryPoint
class HomeFragment : BaseFragment<FragmentHomeBinding>(R.layout.fragment_home) {

    private val viewModel: HomeViewModel by viewModels()


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        binding.postButton.setOnClickListener {
            findNavController().navigate(
                R.id.action_home_to_post
            )
        }

    }

}
  • navigation graph 를 만들 때 지정했던 action 을 navigate() 안의 인자로 넣어주면, 화면을 전환할 수 있습니다.

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)
        binding.activity = this

        initNavigation()
    }

    private fun initNavigation() {
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        navController = navHostFragment.findNavController()
        binding.bottomNavigationView.setupWithNavController(navController)
    }
}
profile
안녕하세요

0개의 댓글