남잭슨의 개발 블로그

[Android Jetpack] AAC Navigation Component -4. Navigation Upgrade (ViewModel with NavGraph Scope & Modularizing(Nested Navgraph) & Multiple-Start-Destination) & 후기,장단점 본문

Android

[Android Jetpack] AAC Navigation Component -4. Navigation Upgrade (ViewModel with NavGraph Scope & Modularizing(Nested Navgraph) & Multiple-Start-Destination) & 후기,장단점

남잭슨 2019. 8. 26. 22:43

2019/03/31 - [Android] - [Android Jetpack] AAC Navigation Component - 1. Navigation 소개,구성 및 개요 , BackStack관리

2019/08/14 - [Android] - [Android Jetpack] AAC Navigation Component -2. SafeArgs & Deeplink & Action

2019/08/18 - [Android] - [Android Jetpack] AAC Navigation Component -3. NavigationUI & Animation/Transition

먼저 위에 글들을 먼저 참고해주세요! 

 

이번글에는 2.1.0에 추가된 내용들인 ViewModel NavGraph Scope, Modularizing(Nested NavGraph), Back-Button 등 

그리고 개인적으로 사용해본 경험, 장단 점에 대해 간략하게 소개할예정이다.

 

Navigation Modularizing

Navigation을 사용하여 간단하게 Modularizing을 할 수 있다.

먼저 모듈화를 위해 Navigation에서 제공하는 Nested Navigation Graphs 에 대해 알아보자

 

 - Nested Navigation Graphs 

Navigation은 Nested Navigation Graphs를 지원한다

여러화면이 개발되다 보면, 전체 NavGraph의 복잡성이 증가되면, 관리하기가 힘들어진다. 

그렇기때문에, 아래처럼 여러개의 NavGraph로 나눠서 관리가 가능하다.

Nested NavigationGraph 를 사용하는 방법은 간단하다 

<Navigation>태그안에 <Navigation>태그를 중첩해서 사용해도 되고. 

따로 정의한후, Root NavGraph에서 아래처럼 <include>로 정의해줘도 된다.

<include app:graph="@navigation/included_graph" />

이를 이용하여 , 모듈화가 가능해진다. 

각 모듈화를 하고, 

root NavGraph에서 아래처럼 <include>를 하면된다.

<?xml version="1.0" encoding="utf-8"?>
<navigation 
    app:startDestination="@id/nav_feature_one">

    <include app:graph="@navigation/nav_feature_one"/>
    <include app:graph="@navigation/nav_feature_two"/>
    <include app:graph="@navigation/nav_feature_three"/>

</navigation>

또, 각 모듈내의 Destination끼리의 이동의 경우에는 Deeplink를 사용하여 구현하면된다.

 

Dynamic Feature Module에 대해서는 아직은 제공하지 않지만, 

올해 안에 지원할 예정이라고 한다.

 

ViewModel with NavGraph Scope

NavGraph의 Destination(Fragment)끼리 ViewModel 공유하는 범위를 지정할수 있다.

아래의 그림처럼 같은 ViewModel을 사용하는 로직을 묶어 ViewModel을 공유하는 기능을 제공한다.

사용방법은 간단하다. 해당 Scope를 Nested Navigation Graph로 정의하고,  아래처럼 선언하여 사용하면 된다.

val factory: ViewModelProviderFactory = ...
val viewModel: MyViewModel
    by navGraphViewModels(R.id.my_graph) { factory }

 

Multiple-Start-Destination ( Multiple-BackStack Navigation )

많은 앱이 BottomNavigation, Tab으로 구현된 앱이라면, 

NavigationUI (이전글 참고)을 사용하여 Top-Level-Destination을 정의하여 사용할수 있지만, 

각 탭마다, 각자의 독립적인 백스택을 가지고 있어야하는 경우가 있다. 

아직까진 공식적으로 지원하진 않지만 googlesample/NavigationAdvanedSampleApp에서 개발을 참조하면된다 .

        fun BottomNavigationView.setupWithNavController(
            navGraphIds: List<Int>,
            fragmentManager: FragmentManager,
            containerId: Int,
            intent: Intent
        ): LiveData<NavController> { 
        	.....
        }

 

아래처럼 사용하면 된다.

        val navGraphIds = listOf(R.navigation.home, R.navigation.list, R.navigation.form)

        // Setup the bottom navigation view with a list of navigation graphs
        val controller = bottomNavigationView.setupWithNavController(
            navGraphIds = navGraphIds,
            fragmentManager = supportFragmentManager,
            containerId = R.id.nav_host_container,
            intent = intent
        )
       

위처럼 탭마다의 NavGraph를 정의하고, BottomNavigationView에 setupWithNavController를 해주면 탭마다 서로다른 독립적인 백스택을 지원하는 화면을 만들 수 있다.

상세한 내용은 https://github.com/googlesamples/android-architecture-components/tree/master/NavigationAdvancedSample

깃허브 소스를 참조하자! 

나의 후기 장/단점

Navigation의 모든 부분을 사용하진 않았지만, 많은 장점을 가지고 있는 것 같다.

아직까진 약간의 부족함?을 느끼지만, 그런 부분을 커버할만큼의 많은 장점을 가지고 있다고 생각이 든다.

개인적으로는 쓰지 않아야할 이유를 찾는게 더 어려운 것 같다

아직은 프로젝트에 도입단계이기 때문에, 큰 단점을 느끼진 못했다. 

 

장점 

앞선 글들에 제공하는 많은 기능과 여러 장점을 써놧지만, 다시한번 장점에 대해 생각해보면

시각적으로 화면 흐름을 볼수있을뿐 아니라, Editor를 사용하여, 화면 흐름을 쉽게 추가/수정이 가능하다.

FragmentTransactions없이 Fragment의 트랜잭션, Back스택 등이 쉽게 관리가 가능하고, 딥링크 처리 및 구현이 간단해졌다, 

화면전환 애니메이션 처리 또한 간단하게 구현이 가능하고, Up,Back버튼 처리가 매우 쉬워졌다. 

추가적으로 SafeArgs, NavGraph 등등 많은 기능을 제공해주어, 쉽게 사용이 가능해진것 같다

 

단점

단점이라고 한다면,

일단 Navigation에서의 Acitvity의 역할이 조금 다르다는 점이다. 

 

"네비게이션 컴포넌트는 Activity의 역할을 기존과 다르게 바라볼 것을 요구합니다.

원래 Activity는 화면의 Entry Point 이면서도 Content와 Navigation Method를 들고있는 Owner 였습니다.

하지만 네비게이션 컴포넌트를 활용하기 위해서는 Entry Point로서의 역할만 보아야 합니다.

Content와 Navigation Method는 모두 NavHost 라는 Fragment에게 위임합니다.

그리고 이는 대부분의 화면을 Single Activity로 설계해야 함을 의미합니다."

 

그렇기 때문에 기존과는 다르게 Single Activity 기반의 설계를 해야하기 때문에,

기존의 프로젝트에서 활용하기에는 마이그레이션 작업이 필요하다. 

(물론 Destination에는 Fragment가 기본이지만, Activity,Dialog를 지원하긴 한다.)

 

또한 사실상 AndroidX로의 마이그레이션 작업이 필요하다.

 

추가적으로

 

 

 

샘플 코드

해당 예제 코드는 아래 깃허브에 구현하였습니다.

(네비게이션 외에도 클린아키텍쳐 스터디를 위해 오픈소스를 진행하고 있습니다. 많은 Star 와 많은 PR,Issue 참여해주세요! )

https://github.com/namjackson/Clean-Architecture-App

 

namjackson/Clean-Architecture-App

Sample app for studying the Android clean architecture. - namjackson/Clean-Architecture-App

github.com

 

다음글 

AAC Navigation Component -1. Navigation 소개, 구성 및 개여, BackStack 관리 ( 이전 글 )

AAC Navigation Component -2. SafeArgs & Deeplink & Action ( 이전 글 )

AAC Navigation Component -3. NavigationUI & Animation/Transition ( 이전 글 )

AAC Navigation Component -4. Navigation Upgrade (ViewModel with NavGraph Scope, Modularizing(Nested NavGraph) & Multiple-Start-Destination) & 나의 후기, 장단점 ( 현재 글 )

 

참고

https://medium.com/@fornewid/io19-jetpack-navigation-33da8811c9de

https://medium.com/swlh/using-the-navigation-component-in-a-modular-world-e7578825962

Comments