ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Navigator - Getting Started
    개발/안드로이드 2020. 4. 20. 23:21

    안드로이드 Navigator 라이브러리는 프래그먼트를 이용해서 화면을 전환하는 작업을 돕는 라이브러리다. 로그인후 메인 화면으로 이동하거나 글 작성하는 UX의 경우 저장하는 작업 까지 여러 화면을 거치게 되는데 이런 경우 여러개의 액티비티를 쓰거나, 매번 FragmentManager를 이용해서 메인 뷰를 차지하고 있는 Fragment를 교체(replace)해줘야 했다. 하지만 Navigator 라이브러리를 사용하면 이런 화면 전환 과정을 XML 파일로 관리할 수 있고 시각화도 가능해서 유지 관리에 도움이 된다.

     

    먼저 XML 파일로 표시하면 이렇고,

     

    fragment_nav_graph.xml

    <?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"
        android:id="@+id/fragment_navi_example"
        app:startDestination="@id/start_fragment">
    
        <fragment
            android:id="@+id/start_fragment"
            android:name="kwony.kotlin.navigate.StartFragment">
            <action
                android:id="@+id/action_first_fragment"
                app:destination="@id/first_fragment"
                app:exitAnim="@anim/fragment_close_exit"/>
        </fragment>
    
        <fragment
            android:id="@+id/first_fragment"
            android:name="kwony.kotlin.navigate.FirstFragment">
            <action
                android:id="@+id/action_second_fragment"
                app:destination="@id/second_fragment"
                app:enterAnim="@anim/slide_in_left"/>
        </fragment>
    
        <fragment
            android:id="@+id/second_fragment"
            android:name="kwony.kotlin.navigate.SecondFragment"/>
    </navigation>

     

    이 정보는 미리보기로 이렇게 표시된다.

     

     

    XML파일을 쭉 훑어보고 난 후 사진을 보면 대강 감이 올텐데 먼저 가장 최상위 startDestination은 시작하는 프래그먼트의 이름이다. 위의 사진에서는 start_fragment 가 이 화면 구성의 시작점이 된다. start_frament에서 action 속성이 하나 있는데 여기서 destination 값은 first_fragment, 바로 앞 start_fragment에서 화살표로 가리키는 클래스다. 마찬가지로 first_fragment 에서도 action 속성이 하나 있는데 여기서의 destination은 second_fragment이고 사진상에서는 second_fragment를 화살표로 가리키고 있다. 이처럼 navigatior 에서는 fragment의 action 속성을 통해 어떤 fragment로 이동해야하는지 정해줄 수 있다. 

     

    app:exitAnim 속성 값은 프래그먼트가 사라질 때 줄 애니메이션 효과다. 기본으로 등록되어 있는 것을 사용해도 되고 직접 커스텀해서 넣을 수도 있다. 반대로 enterAnim은 프래그먼트가 생겨날 때 줄 수 있는 효과다. 간단하게 XML 파일의 형태로 넣을 수 있어서 쉽다.

     

    위에서 설명한 내용을 적용하려면 navigator를 Activity에 넣고 선언한 Fragment들은 action 속성값에 선언된대로 이동하도록 코드를 호출 해야한다. 먼저 Activity 작업에 대한 코드는 다음과 같다.

     

    0. Activity

     

    Class쪽 수정 없이 XML 파일에 이미 만든 navigation 리소스를 넣는 구문만 추가하면 된다. 아래 소스만 넣으면 처음에 StartFragment 를 클래스에서 생성하지 않아도 자동으로 FragmentContainerView가 잡고 있는 영역에 StartFragment가 추가된다. 

     

    그리고 여기서 app:defaultNavHost="true" 로 선언했는데 이렇게 두면 시스템상의 백버튼 액션을 가로채서 이 Navigator에서 사용할 수 있다. 이 말은 즉 SecondFragment로 까지 이동한 상태에서 백버튼을 누르면 그 이전에 stack에 쌓여 있는 FirstFragment로 이동하고 다시 한 번 백버튼을 누르면 그전에 stack에 있는 StartFragment로 이동할 수 있다는 것이다. 프래그먼트가 화면에서 비중있는 역할을 하는 경우 필수적인 속성이 된다.

     

    <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"
        tools:context="kwony.kotlin.di.activity.DaggerRootActivity">
    
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/fragment_nav_di_graph" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

     

    1. StartFragment

     

    StartFragment에서는 FirstFragment로 이동할 수 있는 작업이 있어야 하는데 임의로 TextView를 누르면 그 작업이 호출 되도록 했다. Click Listener 내부를 보면 findnavController().navigate 함수가 부르는데 여기의 인자가 XML에서 StartFragment 내부에 선언한 action 이다.

     

    class StartFragment: DaggerFragment() {
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            fr_nav_tv.text = "StartFragment"
    
            fr_nav_tv.setOnClickListener {
                findNavController().navigate(R.id.action_first_fragment)
            }
        }
    
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            return inflater.inflate(R.layout.fragment_nav_children, container, false)
        }
    }

     

    2. FirstFragment

     

    StartFragment와 코드는 거의 흡사하고 차이가 있는 부분은 아까 선언한 action의 id 값을 바꿔주는 부분만 다르다.

     

    class FirstFragment: DaggerFragment() {
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            fr_nav_tv.text = "FirstFragment"
    
            fr_nav_tv.setOnClickListener {
                findNavController().navigate(R.id.action_second_fragment)
            }
        }
    
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            return inflater.inflate(R.layout.fragment_nav_children, container, false)
        }
    }

     

    이 포스트는 Navigator의 아주 기본적인 기능에 대해서만 소개한 것이라 아직 라이브러리의 장점을 모두 말하지 못했다. 숨겨진 기능을 확인해보고 싶으시다면 구글 문서를 참고하거나 이 카테고리의 다음 글을 기대해도 좋을 것 같다.

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

    MediaCodec - Decoding  (0) 2020.05.24
    MediaCodec - Getting Started  (1) 2020.05.24
    안드로이드 그림자(Shadow) 효과 넣기  (1) 2020.04.18
    Kotlin - Coroutine  (0) 2020.04.15
    Kotlin으로 깔끔한 Builder를 만들어보자  (1) 2020.04.14

    댓글

Designed by Tistory.