개발일지

Android in A..Z - Navigation (Action) 본문

Android (안드로이드)/Navigation

Android in A..Z - Navigation (Action)

강태종 2021. 4. 6. 05:45

Action

Navigation에서 UI 대상간의 이동을 Action이라 하며 Action은 NavGraph에서 정의하고 NavController.navigate()를 사용해서 이동한다.

=> Activity간의 이동을 startActivity()로 이동하는 것과 같음

 

NavGraph에서 UI 대상을 정의할 때 넘겨 받을 Argument를 정의하고 Action을 정의할 때 Animation과 Pop Behavior 등을 정의한다.


NavController 접근방법

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

Animation

Navigation의 장점으로 Action간의 Animation을 쉽게 적용할 수 있다.

    <fragment
        android:id="@+id/AFragment"
        android:name="com.taetae98.navigation.fragment.AFragment"
        android:label="A"
        tools:layout="@layout/fragment_a" >
        <action
            android:id="@+id/action_AFragment_to_BFragment"
            app:destination="@id/BFragment"
            app:enterAnim="@anim/from_right_to_center"
            app:exitAnim="@anim/from_center_to_left"
            app:popEnterAnim="@anim/from_left_to_center"
            app:popExitAnim="@anim/from_center_to_right" />
    </fragment>
  • app:enterAnim : A -> B로 Action할 때 들어오는 UI 대상의 Animation(B의 Animation)
  • app:exitAnim : A -> B로 Action할 때 나가는 UI 대상의 Animation(A의 Animation)
  • app:popEnterAnim : B -> A로 Pop할 때 들어오는 UI 대상의 Animation(A의 Animation)
  • app:popExitAnim : B -> A로 Pop할 때 나가는 UI 대상의 Animation(B의 Animation)

Popup Behavior

    <fragment
        android:id="@+id/CFragment"
        android:name="com.taetae98.navigation.fragment.CFragment"
        android:label="C"
        tools:layout="@layout/fragment_c" >
        <action
            android:id="@+id/action_CFragment_to_DFragment"
            app:destination="@id/DFragment"
            app:enterAnim="@anim/from_right_to_center"
            app:exitAnim="@anim/from_center_to_left"
            app:popEnterAnim="@anim/from_left_to_center"
            app:popExitAnim="@anim/from_center_to_right"
            app:popUpTo="@id/AFragment"
            app:popUpToInclusive="false" />
    </fragment>
  • app:popUpTo : Pop할 때 도착하는 대상 (A -> B -> C -> D 에서 C -> D Action에서 popUpTo를 A로 주면 D에서 Pop할 때 A로 도착한다.)
  • app:popUpToInclusive : popUpTo로 지정한 대상도 Pop할 때 사용한다. (A -> B -> C -> A -> B -> C 같은 순환구조에서 true값을 주면 안전하게 Pop할 수 있다.)

Global Action

여러 UI 대상에서 Action할 때 Global Action을 정의하여 같이 사용할 수 있다.

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/main_nav"
            app:startDestination="@id/mainFragment">

  ...

  <action android:id="@+id/action_global_mainFragment"
          app:destination="@id/mainFragment"/>

</navigation>
viewTransactionButton.setOnClickListener { view ->
    view.findNavController().navigate(R.id.action_global_mainFragment)
}

예제코드

class AFragment : BaseFragment(), DataBinding<FragmentABinding> {
    override val binding: FragmentABinding by lazy { DataBinding.get(this, R.layout.fragment_a) }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        super.onCreateView(inflater, container, savedInstanceState)
        onCreateVewDataBinding()
        onCreateOnMove()

        return binding.root
    }

    private fun onCreateVewDataBinding() {
        binding.lifecycleOwner = this
    }

    private fun onCreateOnMove() {
        binding.setOnMove {
            findNavController().navigate(AFragmentDirections.actionAFragmentToBFragment())
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="onMove"
            type="android.view.View.OnClickListener" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/text_view"
            android:text="A"
            android:textSize="20sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            tools:ignore="HardcodedText" />
        <com.google.android.material.button.MaterialButton
            android:text="Move to B"
            android:onClick="@{onMove}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/text_view"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            tools:ignore="HardcodedText" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Git (예제소스)

github.com/KangTaeJong98/Example/tree/main/Android/Navigation

 

KangTaeJong98/Example

My Example Code. Contribute to KangTaeJong98/Example development by creating an account on GitHub.

github.com

 

Comments