오늘도 더 나은 코드를 작성하였습니까?

Destination으로 이동하기. 본문

Android Jetpack Architecture/Navigation

Destination으로 이동하기.

hik14 2021. 11. 19. 16:10

destionation으로 이동하는 것은 NavController 객체를 사용하여 실행되며 이 객체는 NavHost 내에서 앱 탐색을 관리합니다.

 

 NavHost에는 그에 상응하는 자체 NavController가 있습니다.

 NavController를 사용하면 몇 가지 방식으로 destionation으로 이동할 수 있습니다.

 

NavController를 가져오는 방법

 

kotlin 

  • Fragment.findNavController()
  • View.findNavController()
  • Activity.findNavController(viewId: Int)

NavController를 참조 후 navigate()의 오버로드된 메소드 중  하나를 호출하여 대상 사이를 이동 한다.

 1.  안전한 탐색을 위한 Safe Arg 사용

Safe Args를 사용 설정하면 생성된 코드에 정의한 action의 클래스 및 메서드와 각 발신 및 수신 destination에 상응하는 클래스가 포함됩니다

 

Safe Args는 action이 발생하는 각 destination의 클래스를 생성합니다.

생성된 클래스 이름은 발신 destination 클래스 이름에 'Directions'를 붙입니다.

예를 들어, 발신 대상 이름이 SpecifyAmountFragment라면 생성된 클래스 이름은 SpecifyAmountFragmentDirections가 됩니다.

생성된 클래스에는 발신 destination에서 정의한 각 action의 정적 메서드가 포함됩니다.

이 메서드는 정의된 모든 action 매개변수를 인수로 사용하고 navigate()에 직접 전달할 수 있는 NavDirections 객체를 반환합니다.

override fun onClick(v: View) {
    val amount: Float = ...
    val action =
        SpecifyAmountFragmentDirections
            .actionSpecifyAmountFragmentToConfirmationFragment(amount)
    v.findNavController().navigate(action)
}

 

 2.  ID를 사용한 이동. 

NaviController.navigate(int)는 action 또는 detination의 리소스 ID를 사용합니다.

navigate(action id / destination id) 모두 다 파라미터로 넣을 수 있고, 이동가능하다.

 

다음 코드 스니펫은 ViewTransactionsFragment로 이동하는 방법을 보여줍니다.

viewTransactionsButton.setOnClickListener { view ->
   view.findNavController().navigate(R.id.viewTransactionsAction)
}

버튼의 경우, 아래 예와 같이 Navigation 클래스의 createNavigateOnClickListener() 편의 메서드를 사용하여 detination으로 이동할 수도 있습니다.

button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null))

 

navi graph에 action을 정의하면 탐색은 상응하는 NavAction 클래스를 생성하며 그 클래스에는 다음을 포함하여 action을 위해 정의된 구성이 포함됩니다.

 

Destination:  이동 하려는 destination.

 

Default arguments: 제공된 경우 , 타겟 destination의 기본값을 포함하는 android.os.Bundle

 

vNavigation options: 이 클래스에는 타겟 destination으로 이동하거나 및 타겟 destination에서 다시 돌아오기기 위한 모든 특수 구성이 포함되어 있습니다. 애니메이션 리소스 구성, pop 동작 및 destination이 single top mode에서 시작되어야 하는지 여부를 포함합니다

 

<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/nav_graph"
            app:startDestination="@id/a">

    <fragment android:id="@+id/a"
              android:name="com.example.myapplication.FragmentA"
              android:label="a"
              tools:layout="@layout/a">
        <action android:id="@+id/action_a_to_b"
                app:destination="@id/b"
                app:enterAnim="@anim/nav_default_enter_anim"
                app:exitAnim="@anim/nav_default_exit_anim"
                app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
    </fragment>

    <fragment android:id="@+id/b"
              android:name="com.example.myapplication.FragmentB"
              android:label="b"
              tools:layout="@layout/b">
        <action android:id="@+id/action_b_to_a"
                app:destination="@id/a"
                app:enterAnim="@anim/nav_default_enter_anim"
                app:exitAnim="@anim/nav_default_exit_anim"
                app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                app:popExitAnim="@anim/nav_default_pop_exit_anim"
                app:popUpTo="@+id/a"
                app:popUpToInclusive="true"/>
    </fragment>
</navigation>

navi graph가 inflate되면 이러한 action이 구문 분석되고 해당 NavAction 개체가 그래프에 정의된 구성으로 생성됩니다.

action_b_to_a는 목적지 b에서 목적지로 이동하는 것으로 정의됩니다

action에는 back stack에서 모든 destination을 제거하는 popTo 동작과 함께 애니메이션이 포함됩니다.

이러한 모든 설정은 NavOptions로 캡처되고 NavAction에 연결됩니다.

 

Apply NavOptions programmatically

탐색 그래프 XML 내에서 NavOptions를 지정하는 방법을 보여줍니다.

그러나 특정 옵션은 빌드 시 알 수 없는 제약 조건에 따라 달라질 수 있습니다.

findNavController().navigate(
    R.id.action_fragmentOne_to_fragmentTwo,
    null,
    navOptions { // Use the Kotlin DSL for building NavOptions
        anim {
            enter = android.R.animator.fade_in
            exit = android.R.animator.fade_out
        }
    }
)

 

* 프로그래밍 방식으로 적용된 NavOptions는 XML에 설정된 모든 옵션을 재정의합니다.

 

Navigate using DeepLinkRequest

 

아래 같이 navigate(NavDeepLinkRequest)을 사용하여  implicit deep link destination으로 직접 이동할 수 있습니다

val request = NavDeepLinkRequest.Builder
    .fromUri("android-app://androidx.navigation.app/profile".toUri())
    .build()
findNavController().navigate(request)

Uri 외에도 NavDeepLinkRequest는 actions 및 MIME type이 있는 딥 링크도 지원합니다.

 

Request에 작업을 추가하려면 fromAction() 또는 setAction()을 사용

Request에 MIME 유형을 추가하려면 fromMimeType() 또는 setMimeType()을 사용

 

NavDeepLinkRequest가 implicit deep link destination과 올바르게 일치하려면 URI, actions 및 MIME 유형이 모두 대상의 NavDeepLink와 일치해야 합니다

 

URI는 패턴과 일치해야 하고 actions은 정확히 일치해야 하며 MIME 유형은 관련되어야 합니다(예: "image/jpg"는 "image/*"와 일치).

 

action 또는 detination ID를 사용하는 탐색과 달리 detination이 표시되는지 여부에 관계없이 그래프의 딥 링크로 이동할 수 있습니다.

현재 그래프의 destination이나 완전히 다른 그래프의 destination으로 이동할 수 있습니다.

 

NavDeepLinkRequest를 사용하여 탐색할 때 백 스택은 재설정되지 않습니다.

NavDeepLinkRequest은 탐색할 때 백 스택이 교체되는 deepLink navigation과 다릅니다.

popUpTo 및 popUpToInclusive는 ID를 사용하여 탐색한 것처럼 , 백 스택에서destination을 제거합니다.

 

*편의를 위해 DeepLinkRequest에서 Uri를 래핑하는 navigation(Uri)을 사용할 수도 있습니다.