Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Navigation 살펴보기

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Navigation 살펴보기

'19년 GDG Android at Pangyo! (4월 밋업)의 'Navigation 살펴보기' 세션 발표자료입니다.

Navigation 살펴보기(more):
https://link.medium.com/gTVrhA4GjW

Sample Projects:
https://github.com/fornewid/GDGAndroid-atPangyo-2019-Navigation-Sample

Avatar for Sungyong An

Sungyong An

April 30, 2019

More Decks by Sungyong An

Other Decks in Programming

Transcript

  1. Navigation이란? • Android Jetpack (’18.5 ~ ’19.3(Stable) ~ 현재) •

    앱 내의 화면 탐색을 다루는 Component • 레이아웃처럼 XML로 Navigation Graph를 관리 Link: https://youtu.be/8GCXtCjtg40 https://youtu.be/2k8x8V77CrU
  2. Navigation 클래스, 인터페이스 • NavHost / NavController • NavGraph •

    Navigator • NavDestination • NavDirections / NavArgs • NavigationUI <?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/navigation" app:startDestination="@+id/splash"> <fragment android:id="@+id/splash" android:name="soup.gdg.navigation.sample.ui.splash.SplashFragment" tools:layout="@layout/fragment_splash" /> <fragment android:id="@+id/login" android:name="soup.gdg.navigation.sample.ui.login.LoginFragment" tools:layout="@layout/fragment_login"> <argument android:name="nextDestinationIsUp" android:defaultValue="false" app:argType="boolean" /> </fragment> <fragment android:id="@+id/home" android:name="soup.gdg.navigation.sample.ui.home.HomeFragment" android:label="@string/title_home" tools:layout="@layout/fragment_home" /> <fragment android:id="@+id/detail" android:name="soup.gdg.navigation.sample.ui.detail.DetailFragment" tools:layout="@layout/fragment_detail"> <argument android:name="movieId" app:argType="string" app:nullable="false" /> <deepLink app:uri="origin://detail/{movieId}" /> </fragment> <fragment android:id="@+id/settings" android:name="soup.gdg.navigation.sample.ui.settings.SettingsFragment" tools:layout="@layout/fragment_settings" /> <activity android:id="@+id/web" android:name="soup.gdg.navigation.sample.ui.web.WebActivity" tools:layout="@layout/activity_web"> <argument android:name="data" app:argType="soup.gdg.navigation.sample.ui.web.WebScene" /> </activity> <include app:graph="@navigation/nav_graph_profile" /> <dialog_fragment android:id="@+id/login_confirm" android:name="soup.gdg.navigation.sample.ui.login.LoginConfirmDialogFragment" /> </navigation> = Fragment = Intent / Bundle = UI Helper = Activity / FragmentManager
  3. 기본 원칙 • 고정된 시작점 • Navigation 상태는 Destination Stack으로

    표현 • App Task 내에서 Up과 Back은 동일 • Up 버튼은 App을 종료 불가능 • 딥링크는 일반 탐색과 동일하게 처리 Link: https://developer.android.com/guide/navigation/navigation-principles App Task … Back or Up App Task … DeepLink
  4. Navigate Forward Activity Activity startActivity Fragment Fragment ft.replace navigate NavDestination

    NavDestination • 다음 화면으로 이동하기 Bundle Bundle Bundle NavDirections NavArgs
  5. Navigate Forward // For Activity val intent = Intent(this, LoginActivity::class.java)

    startActivity(intent) // For Fragment val fragment = LoginFragment() fragmentManager .beginTransaction() .replace(R.id.container, fragment) .addToBackStack("back stack name") .commit() intent.putExtra("name", “value")
 
 
 fragment.arguments = bundleOf("name" to "value")
  6. Navigate Forward // Without Arguments navController.navigate(R.id.login) navController.navigate( SplashFragmentDirections.actionToLogin()) // With

    Arguments val arguments = bundleOf("name" to "value") navController.navigate(R.id.login, arguments) navController.navigate( SplashFragmentDirections.actionToLogin(/* name */ “value") ) <!-- In Navigation XML --> <action android:id="@+id/action_to_login" app:destination=“@id/login" /> val navController = findNavController() <!-- In Navigation XML --> <argument android:name="name" app:argType="string" />
  7. Navigate Backward Activity Activity finish Fragment Fragment fm.popBackStack navigateUp popBackStack

    NavDestination NavDestination Result X X " • 이전 화면으로 되돌아가기
  8. Navigate Backward val navController = findNavController() navController.navigateUp() — (1) navController.popBackStack()

    — (2) navController.popBackStack( /* destinationId */ R.id.home, /* inclusive */ false ) — (3) App Task … (1,2,3) (2,3) (3)
  9. Find NavController • 모든 요청은 NavController를 통한다 • Kotlin: Link:

    https://developer.android.com/guide/navigation/navigation-getting-started#navigate_to_a_destination Fragment.findNavController() View.findNavController() Activity.findNavController(viewId: Int)
  10. // For Kotlin val navController = findNavController() navController.navigate( NavigationDirections.actionToLogin() )

    Navigate Forward (+ Pop Up) <!-- In Navigation XML --> <action android:id="@+id/action_to_login" app:destination="@id/login" app:popUpTo="@id/splash" app:popUpToInclusive="true" /> NavigationDirections.actionToLogin(), NavOptions.Builder() .setPopUpTo(R.id.login, true) .build() ) navOptions { popUpTo(R.id.splash) { inclusive = true } } }
  11. Navigate Forward (+ Single Top) Before A After B B

    • 같은 화면을 연속으로 쌓지 않고, 다음 화면으로 이동하기
  12. // For Kotlin val navController = findNavController() navController.navigate( NavigationDirections.actionToDetail(id) )

    Navigate Forward (+ Single Top) <!-- In Navigation XML --> <action android:id="@+id/action_to_detail" app:destination="@id/detail" app:launchSingleTop="true" /> NavigationDirections.actionToDetail(id), NavOptions.Builder() .setLaunchSingleTop(true) .build() ) navOptions { launchSingleTop = true } )
  13. Navigation Structure NavHost (NavHostFragment) NavController NavGraph NavigatorProvider Navigator NavBackStackEntry NavDestination

    ‘B’ NavDestination ‘A’ NavDirections NavArgs • 직접 사용할 때는 NavController, NavDirections, NavArgs만 알면 된다.
  14. NavGraph • 앱 화면들을 정의하는 리소스 파일
 
 ㄴ res/navigation/{graph_file_name}.xml

    • NavDestination는 Fragment / Activity / NavGraph가 가능 • 각 화면으로의 Action을 정의할 수 있음 • 각 화면의 Arguments를 정의할 수 있음
  15. NavGraph (1/2) <navigation android:id="@+id/navigation" app:startDestination="@+id/splash"> <fragment android:id="@+id/splash" android:name=".ui.splash.SplashFragment" tools:layout="@layout/fragment_splash"> <action

    android:id="@+id/action_to_login" app:destination="@id/login" app:enterAnim="@anim/slide_in_right" app:exitAnim="@anim/slide_out_left" app:popEnterAnim="@anim/slide_in_left" app:popExitAnim=“@anim/slide_out_right" /> </fragment> ... <— NavGraph <- NavGraph ID <— Fixed start destination
 <— Fragment NavDestination <- NavDestination ID
 
 
 <— A NavAction in NavDirections (Local) <- NavAction ID
 <| Transition
 | Animations
 | of NavAction
 |
  16. NavGraph (2/2) <activity android:id="@+id/web" android:name=".ui.web.WebActivity"> <argument android:name="data" app:argType=".ui.web.WebScene" app:nullable="false" />

    </activity> <include app:graph="@navigation/nav_graph_profile" /> <action android:id="@+id/action_to_login" app:destination="@id/login" /> </navigation> <— Activity NavDestination
 
 
 <— A field of NavArgs
 
 
 
 
 // Nested NavGraph
 
 <— A NavAction for NavDirections (Global)
  17. SafeArgs (NavArgs) • Fragment 또는 Activity의 Bundle에서 Arguments 꺼내기 •

    Kotlin: Link: https://developer.android.com/guide/navigation/navigation-pass-data#Safe-args val args: WebActivityArgs by navArgs() args.data // WebScene
  18. NavHost • NavController 제공하는 컨테이너 • NavHostFragment라는 구현체를 기본 제공

    • Fragment 계층 구조:
 
 MainActivity • NavHostFragment • SplashFragment • LoginFragment • …
  19. NavHost <!-- In Layout XML --> <fragment android:id="@+id/navHostFragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent"

    android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" /> ũ app:defaultNavHost="true" // For Kotlin val hostFragment = NavHostFragment.create(R.navigation.nav_graph) supportFragmentManager.beginTransaction() .replace(R.id.nav_host, hostFragment) .setPrimaryNavigationFragment(hostFragment) .commit()
  20. 못다한 얘기들 • Handling Shared Elements • Handling Back Pressed

    Events • NavArgs using @Parcelize class • NavGraph Scope ViewModel • Dialog NavDestination • NavigationUI with multiple start destinations • Handling SystemUI • Handling NavResult? Link: https://link.medium.com/gTVrhA4GjW
  21. Dependencies (AndroidX) def nav_version = “2.1.0-alpha02" // 2.0.0 (Stable) //

    For Java implementation "androidx.navigation:navigation-fragment:$nav_version" implementation "androidx.navigation:navigation-ui:$nav_version"
 // For Kotlin implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" /* SafeArgs - project/build.gradle */ classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" // For Kotlin apply plugin: “androidx.navigation.safeargs.kotlin" // For Java apply plugin: “androidx.navigation.safeargs" Link: https://developer.android.com/jetpack/androidx/releases/navigation
  22. Dependencies (Pre-AndroidX) def nav_version = "1.0.0" // For Java implementation

    "android.arch.navigation:navigation-fragment:$nav_version" implementation "android.arch.navigation:navigation-ui:$nav_version" // For Kotlin implementation "android.arch.navigation:navigation-fragment-ktx:$nav_version" implementation "android.arch.navigation:navigation-ui-ktx:$nav_version" /* SafeArgs - project/build.gradle */ classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:$nav_version" Link: https://developer.android.com/jetpack/androidx/releases/navigation#pre-androidx_dependencies
  23. Conclusion • 화면 탐색을 다루는 '공식적인' 방법 + 1 •

    직접적인 FragmentTransaction 필요 X • 다수의 Fragments 관리가 필요한 경우, 고려해볼 것 • 다음/이전 화면으로의 자유로운 이동 기능 • 아쉬운 부분은 존재 (Ex. 이전 화면으로 결과 전달 불가능) • 사실상 AndroidX로 전환 필요
  24. More References • Version Release
 https://developer.android.com/jetpack/androidx/releases/navigation • Official Guide
 https://developer.android.com/guide/navigation

    • CodeLab
 https://codelabs.developers.google.com/codelabs/android-navigation • Source Code
 android-arch-navigation-release
 androidx-navigation-release