본문 바로가기

안드로이드

[And] navigation #1 - 기본 사용법

반응형

Navigation?

Navigation 은 Activity - Fragment 구조에서 빠질 수 없는 Transaction을 보다 쉽게 구현하기 위한 Jetpack Component이다.

Transaction 외에서 애니메이션, 딥링크, 뷰 모델 공유들의 기능을 가지고 있다.

시작하기

-- project ------------

dependencies {

     classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.0-alpha06"

}

-- app ----------------

apply plugin: "androidx.navigation.safeargs.kotlin"

dependencies {
    implementation "androidx.navigation:navigation-runtime-ktx:2.2.2"
    implementation "androidx.navigation:navigation-fragment-ktx:2.2.2"
    implementation "androidx.navigation:navigation-ui-ktx:2.2.2"
}

Navigation Graph 만들기

위의 사진처럼 새로운 리소스를 만들 때 Resource Type을 Navigation으로 선택하여 만들어 준다.
그리고 만들어진 리소스의 Design 탭으로 Navaigation 툴을 확인할 수 있다.

 

툴에서는 상단의 + 버튼을 통해 화면들을 추가하고, 드래그하여 선을 연결하면 기본적인 그래프의 구성이 완료된다.

시작 프래그먼트는 상단의 집모양 버튼을 통해서 지정이 가능하다.

위의 그림처럼 그래프를 구성하면 f1 -> f12, f1 -> f12 -> f121로 이동할 수 있다.

 

위의 그래프에서 선들의 Action 이라고 부른다.

Action 의 세부사항으로 id 와 시작 지점, 끝 지점, 애니메이션 등을 지정할 수 있다. 

id 는 지정하지않으면 "시작화면_to_끝화면" 식으로 자동으로 부여된다.

Navigation Graph 연결하기

<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">

    <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:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />


</androidx.constraintlayout.widget.ConstraintLayout>

연결하는 방법은 액티비티의 레이아웃의 framgent, FragmentContainerView 코드를 위와 같이 작성하면 액티비티에서 아무런 코드를 작성하지 않아도 Graph의 시작 지점부터 화면에 나오게 된다.

val host = NavHostFragment.create(R.navigation.nav_graph)
    supportFragmentManager.beginTransaction()
        .replace(R.id.nav_host_fragment, host)
        .setPrimaryNavigationFragment(host)
        .commit()

FrameLayout에서 Navigation을 적용하려면 위의 방식으로 사용할 순 없고, 액티비티에서 Transaction을 통해 그래프를 추가시켜 주어야 한다.

Navigation Graph 이동해보기

Navigation에서의 이동은 NavController 를 이용해서 이루어진다.


NavController는 프래그먼트에서는 findNavController 를 통해서,

View에서는 Navigation.findNavController(view) 를 통해서 가져올 수 있다.

firstButton.setOnClickListener { view ->
    //1. findNavController().navigate(Fragment12Directions.actionFragment12ToFragment121())
    //2. findNavController().navigate(R.id.action_fragment12_to_fragment121)
    //3. Navigation.findNavController(view).navigate(Fragment12Directions.actionFragment12ToFragment121())
}
firstButton.setOnClickListener(
    4. Navigation.createNavigateOnClickListener(R.id.action_fragment12_to_fragment121)
)

위의 코드는 다 같은 동작을 하는 코드이다.

 

NavController.navigate 함수를 통해서 이동이 가능하며, 인자로는 Id, Directions, deeplink가 들어갈 수 있다.

 

id 는 액션의 id를 뜻한다.
Directions 역시 자동으로 만들어지는 코드이고, ClassName + Directions의 이름을 가지고 이동할 수 있는 액션들을 담고 있다.
함수명은 액션의 id를 따라서 만들어진다.

 

4번처럼 Navigation.createNavigateOnClickListener 함수를 통해서 바로 인자로 넘길 수 도있다.

backButton.setOnClickListener {
    //findNavController().navigateUp()
    //findNavController().popBackStack()
    findNavController().popBackStack(R.id.fragment1,false)
}

navigateUp, popBackStack 을 통해서 가능하며 각각 up 버튼, back 버튼 시에 동작한다.

popBackStack의 인자로 fragment의 id 값 ( navigation에서 지정한 )을 주게 되면 해당 화면까지 한 번에 돌아갈 수 있다.

값 넘기기

번들로 던지기
findNavController().navigate(
    R.id.action_fragment1_to_fragment11,
    Bundle().apply { putFloat("Float", 1f) })

    arguments?.get("Float")

기존의 Fragment처럼 bundle을 이용해서 던져주면 된다.

Safe Args 사용하기

우선 Navigation 툴로 가서 프래그먼트가 받을 인자를 지정해 주어야 한다.

val number = 5
findNavController().navigate(Fragment1Directions.actionFragment1ToFragment12( number ))

함수에 기존에는 없던 인자가 생긴 것을 확인할 수 있고, 해당 인자를 통해 데이터를 넘길 수 있게 되었다.
( 없으면 빌드를 다시 하면 나온다. )

val args: Fragment11Args by navArgs()

args.number // 5

해당 프래그먼트에서는 위와 같이 인자를 내가 지정한 이름으로 불러와서 사용할 수 있다.

반응형

'안드로이드' 카테고리의 다른 글

Android Espresso #1 - 시작  (0) 2020.06.24
[And] navigation #2 - 딥 링크  (0) 2020.06.24
안드로이드 paging 3.0 #2 - LoadState  (0) 2020.06.16
안드로이드 Paging 3.0 #1 - 맛보기  (5) 2020.06.13
Dagger - Hilt 간보기  (0) 2020.06.11