경험의 기록

 

2021.04.10 - [안드로이드/AAC, MVVM] - [Android] JetPack Navigation 사용하여 Fragment 관리하기

 

[Android] JetPack Navigation 사용하여 Fragment 관리하기

developer.android.com/guide/navigation/navigation-getting-started 탐색 구성요소 시작하기  | Android 개발자  | Android Developers 이 주제는 탐색 구성요소를 설정하고 사용하는 방법을 설명합니다. 탐색..

hanyeop.tistory.com

네비게이션 라이브러리를 사용하면

프래그먼트 간의 전환을 좀더 간결하게 할 수 있다.

 

또한 Safe Arg를 사용하면

프래그먼트 간의 데이터 통신도 쉽게 할 수 있다.

 

 


1️⃣ 기본 사용법

종속성 추가

// Navigation
    def nav_version = "2.3.5"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

 

Navigation graph 추가

res > new > Android Resource File 에서 resource type Navigation 으로 추가해준다.

 

프래그먼트 추가

프래그먼트를 추가해주고

드래그로 액션을 연결해준다.

 

메인 xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    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/fragmentContainerView"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>

프래그먼트컨테이너뷰를 생성해준다.

navGraph 를 아까 만든 네비게이션으로,

name을 androidx.navigation.fragment.NavHostFragment 으로 설정해주고

 

안드로이드에서 뒤로가기키를 눌렀을때 이 화면으로 오게 하기 위해서

app:defaultNavHost="true" 로 설정해준다.

 

메인액티비티

class MainActivity : AppCompatActivity() {
    // 네비게이션 선언
    private lateinit var navController: NavController

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

        // 네비게이션 연결
        val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
        navController = navHostFragment.findNavController()

        // 앱 바 생성
        val appBarConfiguration = AppBarConfiguration(navController.graph)
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

    // 뒤로가기
    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp() || super.onSupportNavigateUp()
    }
}

액티비티에서 네비게이션을 생성해주고

 

프래그먼트

class OneFragment : Fragment(R.layout.fragment_one) {

    private var _binding : FragmentOneBinding? = null
    private val binding get() = _binding!!

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

        _binding = FragmentOneBinding.bind(view)

        // 액션 연결
        binding.apply {
            button.setOnClickListener {
                val action = R.id.action_oneFragment_to_twoFragment
                findNavController().navigate(action)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        _binding = null
    }
}

사용할 프래그먼트에서 액션을 지정해준다.

뷰바인딩을 사용하였으며 버튼 클릭시 두번째 프래그먼트로 넘어가도록 했다.

버튼을 클릭하면

 

잘 전환되는 것을 확인할 수 있다.

 

 

2️⃣ 데이터 통신

// Safe Args
        def nav_version = "2.3.5"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"

project 단위의 그래들에 추가해주고

 

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

module 단위의 그래들에 플러그인을 추가해준다.

 

이제 데이터를 받을 쪽에서

Arguments를 추가할 수 있다.

 

❗ 단, Arguments의 이름의 첫글자를 대문자로 설정할 경우 오류가 나니 주의해야한다.

 

일반적인 자료형은 그냥 사용할 수 있으나

Data class를 사용하기 위해서는 Parcelable 를 사용해야한다.

 

Parcelable 사용하기

plugins {
    id 'kotlin-parcelize'
}

플러그인을 추가해주고

 

@Parcelize
data class User(
    val name : String,
    val age : Int
) : Parcelable

전달할 데이터클래스에

@Parcelize 어노테이션을 사용하면 Parcelable를 자동으로 만들어준다.

 

첫 번째 프래그먼트

// 세번째 화면으로 이동
            submitButton.setOnClickListener {
                val user = User(nameEditView.text.toString(),ageEditView.text.toString().toInt())
                val action = OneFragmentDirections.actionOneFragmentToThreeFragment(user = user, name = "Han")
                findNavController().navigate(action)
            }

데이터클래스와 임의의 데이터가 전달되도록 하고

 

세 번째 프래그먼트

class ThreeFragment : Fragment(R.layout.fragment_three) {

    private val args by navArgs<ThreeFragmentArgs>()

    private var _binding : FragmentThreeBinding? = null
    private val binding get() = _binding!!

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

        _binding = FragmentThreeBinding.bind(view)

        binding.apply {
            nameText.text = args.user.name
            ageText.text = args.user.age.toString()
            Log.d("tst5", "${args.name}")
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        _binding = null
    }
}

navArgs를 선언해주면

받은 값을 사용할 수 있다.

 

임의의 데이터를 작성하고 버튼을 누르면

 

데이터가 잘 전달된 것을 확인할 수 있고

로그에 임의의 데이터가 찍힌 것을 확인할 수 있다.

 

 

 

 

https://github.com/HanYeop/AndroidStudio-Practice2/tree/master/NavigationEx

 

HanYeop/AndroidStudio-Practice2

(2021.05.20~) 안드로이드 학습 내용 저장소. Contribute to HanYeop/AndroidStudio-Practice2 development by creating an account on GitHub.

github.com

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading