이 포스트는 안드로이드 공식 홈페이지 Codelab 을 기반으로 작성되었습니다.
Navigation 시스템을 사용하면 Action을 통해 탐색할 수도 있다. NavGraph
에서 표시된 선은 Action을 시각적으로 표시한 것이다.
Action을 이용한 탐색은 Destination을 이용한 탐색과 비교해 다음과 같은 이점이 있다.
1. 앱에서 탐색 경로를 시각화할 수 있다.
2. Action에는 전환 애니메이션, 인수 값, 백 스택 동작 등 개발자가 설정할 수 있는 추가 속성이 포함될 수 있다.
3. safe args 플러그인을 사용할 수 있다.
아래는 flow_step_one_dest
및 flow_step_two_dest
를 연결하는 작업의 시각화 및 XML이다.
<fragment
android:id="@+id/flow_step_one_dest"
android:name="com.example.android.codelabs.navigation.FlowStepFragment">
<argument
.../>
<action
android:id="@+id/next_action"
app:destination="@+id/flow_step_two_dest">
</action>
</fragment>
<fragment
android:id="@+id/flow_step_two_dest"
android:name="com.example.android.codelabs.navigation.FlowStepFragment">
<!-- ...removed for simplicity-->
</fragment>
다음은 flow_step_two_dest
를 home_dest
에 연결하는 또 다른 예이다.
<fragment
android:id="@+id/home_dest"
android:name="com.example.android.codelabs.navigation.HomeFragment"
.../>
<fragment
android:id="@+id/flow_step_two_dest"
android:name="com.example.android.codelabs.navigation.FlowStepFragment">
<argument
.../>
<action
android:id="@+id/next_action"
app:popUpTo="@id/home_dest">
</action>
</fragment>
이제 Navigate with Action 버튼을 이용해서 연결해보자.
Design 모드에서 mobile_navigation.xml
파일을 연다.
화살표를 home_dest
에서 flow_step_one_dest
로 드래그한다.
작업 화살표를 선택한 상태에서 작업 속성을 아래 이미지와 같이 변경해 애니메이션 효과를 추가해준다.
Text 탭을 클릭한다. 아래와 같이 파일이 변경된 것을 확인할 수 있다.
mobile_navigation.xml
<fragment android:id="@+id/home_dest"
...>
<action android:id="@+id/next_action"
app:destination="@+id/flow_step_one"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
HomeFragment.kt
를 연다.navigate_action_button
에 클릭 리스너를 추가한다.HomeFragment.kt
view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.next_action, null)
)
Navigation 구성요소에는 대상 및 작업에 지정된 인수에 안전하게 액세스하기 위해 간단한 객체 및 빌더 클래스를 생성하는 safe args라는 Gradle 플러그인이 있다.
safe args 플러그인을 사용하면 다음과 같은 코드 변경이 가능하다.
// 변경 전 (Before)
val username = arguments?.getString("usernameKey")
// 변경 후 (After)
val username = args.username
mobile_navigation.xml
을 열고 flow_step_one_dest
대상에서 인수가 정의되는 방식을 확인하면 아래와 같다.<fragment
android:id="@+id/flow_step_one_dest"
android:name="com.example.android.codelabs.navigation.FlowStepFragment"
tools:layout="@layout/flow_step_one_fragment">
<argument
android:name="flowStepNumber"
app:argType="integer"
android:defaultValue="1"/>
<action...>
</action>
</fragment>
<argument>
태그를 통해 safeargs는 FlowStepFragmentArgs
라는 클래스를 생성한다.
XML에 android:name="flowStepNumber"
로 지정된 flowStepNumber
라는 인수가 포함되어 있으므로 생성된 FlowStepFragmentArgs
클래스에는 getter와 setter가 있는 flowStepNumber
변수가 포함된다.
아래에 표시된 코드를 주석처리한다.
// Comment out this line
// val flowStepNumber = arguments?.getInt("flowStepNumber")
safe args를 사용하도록 아래 코드를 추가한다.
val safeArgs: FlowStepFragmentArgs by navArgs()
val flowStepNumber = safeArgs.flowStepNumber
safe args를 사용하여 인수 추가 여부와 상관없이 유형에 안전한 방식으로 탐색할 수도 있다. Safe Args를 통해 생성된 Direction 클래스를 사용하면 된다.
Direction 클래스는 Action이 있는 모든 Destination에 대해 생성된다. Direction 클래스에는 Destination에 있는 모든 Action의 메소드가 포함되어 있다.
예를 들어 HomeFragment.kt의 navigation_action_button
클릭 리스너는 다음과 같이 변경될 수 있다.
// Note the usage of curly braces since we are defining the click listener lambda
view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener {
val flowStepNumberArg = 1
val action = HomeFragmentDirections.nextAction(flowStepNumberArg)
findNavController().navigate(action)
}