본문 바로가기
개발/Android

Android Jetpack Navigation 사용하여 parameter 전달하기

by Dev Aaron 2020. 11. 8.
반응형

Android Jetpack의 Navigation은 앱 개발 방식을 꽤 흥미롭게 바꿔줍니다. Single Activity를 지향하는 Architecture 모델을 사용하도록 권하는 방식이랄까? 물론 Multi Activity를 사용해도 문제될 것은 없습니다.

​어쨋든 본 포스팅에서는 Navigation을 사용했을 때, parameter를 어떻게 전달하는지에 대해 다루려고 합니다.

​기존 Activity나 Fragment에서 다음 화면으로 데이터를 전달하기 위해서는 Bundle 형태로 데이터를 실어 보냈습니다. ​우선 결론적으로 어떻게 전달하는지 칼퇴지향에 적용된 사례를 통해 보여드리고자 합니다.

1. Safe Args 플러그인 추가

본 기능을 적용하기 위해 gradle plugin을 추가합니다.

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

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

2. Destination에 전달 받을 데이터 선언

아래 스크린샷에서처럼 nav_graph.xml 파일에서 데이터를 전달받을 view를 선택하면 오른쪽에 Arguments 항목이 보입니다.

+ 버튼을 누르면 아래와 같이 변수 명, 자료형, Nullable, 기본값 등 전달 받을 데이터에 대한 정보를 정의할 수 있습니다.

3. Build

상단 메뉴에서 Build > Rebuild project 를 선택하여 프로젝트를 다시 빌드합니다.

이 과정을 통해 새로운 클래스가 자동으로 생성되며, 다음 단계에서 새로 생긴 이 클래스를 사용합니다.​

4. Destination으로 데이터 전달하기

이제 Source(출발지) view에서 Destination으로 Navigation을 하면서 데이터를 어떻게 전달하는지 보겠습니다.

본 포스팅에서는 칼퇴지향 앱에 실제 적용된 코드를 예로 설명하기 때문에 실제 사용된 클래스 명을 통해 설명을 하겠습니다.​

2개의 ui Fragment가 있습니다: CalendarFragment, TimerFragment
CalendarFragment에서 버튼을 누르면, TimerFragment로 화면 전환을 하게 되며 이때 Long 타입의 id 값을 전달해야 합니다.

따라서 #2 단계에서 TimerFragment에 전달 받을 데이터에 대한 정보를 선언했다고 보시면 되겠습니다.

그리고 #3 단계에서 빌드를 하게 되면 아래와 같은 CalendarFragmentDirections 클래스가 자동으로 생성됩니다.

class CalendarFragmentDirections {
    ...
    fun actionCalendarFragmentToTimerFragment(id: Long): NavDirections
    ...
}

따라서 CalendarFragment에서는 TimerFragment로 화면 전환하기 위해 아래와 같이 코드를 작성하면 됩니다.

val action = CalendarFragmentDirections.actionCalendarFragmentToTimerFragment(id)
findNavController().navigate(action)

5. 전달 받은 데이터 사용하기

이제 TimerFragment에서 전달 받은 데이터를 사용하는 방법을 보여드리겠습니다. 먼저 TimerFragment에 아래와 같이 val 선언을 합니다. TimerFragmentArgs 역시 Step 3 빌드 과정에서 자동으로 생성되는 클래스입니다.

import androidx.navigation.fragment.navArgs

class TimerFragment: Fragment() {
    private val args: TimerFragmentArgs by navArgs()
    ...
}

그리고 원하는 곳에서 아래와 같이 사용하면 됩니다.

import androidx.navigation.fragment.navArgs

class TimerFragment: Fragment() {
    private val args: TimerFragmentArgs by navArgs()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        Log.d(TAG, "id: ${args.id}")
    }
}
반응형