Slide 1

Slide 1 text

Navigation 살펴보기 안성용

Slide 2

Slide 2 text

자기소개 SOUP [email protected] 안성용 Android Developer at NAVER

Slide 3

Slide 3 text

Navigation이란? • Android Jetpack (’18.5 ~ ’19.3(Stable) ~ 현재) • 앱 내의 화면 탐색을 다루는 Component • 레이아웃처럼 XML로 Navigation Graph를 관리 Link: https://youtu.be/8GCXtCjtg40 https://youtu.be/2k8x8V77CrU

Slide 4

Slide 4 text

Google I/O 2019 Link: https://events.google.com/io/schedule/events/2d0cb491-325a-48fb-8eea-6a9452f3b33b

Slide 5

Slide 5 text

시작하기 전에 Link: https://developer.android.com/guide/navigation

Slide 6

Slide 6 text

⚠ 모든 코드는 Kotlin으로 작성되었습니다.

Slide 7

Slide 7 text

Navigation 클래스, 인터페이스 • NavHost / NavController • NavGraph • Navigator • NavDestination • NavDirections / NavArgs • NavigationUI = Fragment = Intent / Bundle = UI Helper = Activity / FragmentManager

Slide 8

Slide 8 text

기본 원칙 • 고정된 시작점 • 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

Slide 9

Slide 9 text

How to Use

Slide 10

Slide 10 text

Navigate Forward Activity Activity startActivity Fragment Fragment ft.replace navigate NavDestination NavDestination • 다음 화면으로 이동하기 Bundle Bundle Bundle NavDirections NavArgs

Slide 11

Slide 11 text

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")

Slide 12

Slide 12 text

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") ) val navController = findNavController()

Slide 13

Slide 13 text

Navigate Backward Activity Activity finish Fragment Fragment fm.popBackStack navigateUp popBackStack NavDestination NavDestination Result X X " • 이전 화면으로 되돌아가기

Slide 14

Slide 14 text

Navigate Backward // For Activity setResult(Activity.RESULT_OK) finish() // For Fragment fragmentManager.popBackStack()

Slide 15

Slide 15 text

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)

Slide 16

Slide 16 text

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)

Slide 17

Slide 17 text

• 특정 화면까지 되돌아간 후, 다음 화면으로 이동하기 Navigate Forward (+ Pop Up) After Before

Slide 18

Slide 18 text

// For Kotlin val navController = findNavController() navController.navigate( NavigationDirections.actionToLogin() ) Navigate Forward (+ Pop Up) NavigationDirections.actionToLogin(), NavOptions.Builder() .setPopUpTo(R.id.login, true) .build() ) navOptions { popUpTo(R.id.splash) { inclusive = true } } }

Slide 19

Slide 19 text

Navigate Forward (+ Single Top) Before A After B B • 같은 화면을 연속으로 쌓지 않고, 다음 화면으로 이동하기

Slide 20

Slide 20 text

// For Kotlin val navController = findNavController() navController.navigate( NavigationDirections.actionToDetail(id) ) Navigate Forward (+ Single Top) NavigationDirections.actionToDetail(id), NavOptions.Builder() .setLaunchSingleTop(true) .build() ) navOptions { launchSingleTop = true } )

Slide 21

Slide 21 text

Navigation Structure NavHost (NavHostFragment) NavController NavGraph NavigatorProvider Navigator NavBackStackEntry NavDestination ‘B’ NavDestination ‘A’ NavDirections NavArgs • 직접 사용할 때는 NavController, NavDirections, NavArgs만 알면 된다.

Slide 22

Slide 22 text

NavGraph • 앱 화면들을 정의하는 리소스 파일
 
 ㄴ res/navigation/{graph_file_name}.xml • NavDestination는 Fragment / Activity / NavGraph가 가능 • 각 화면으로의 Action을 정의할 수 있음 • 각 화면의 Arguments를 정의할 수 있음

Slide 23

Slide 23 text

NavGraph (1/2) ... <— NavGraph <- NavGraph ID <— Fixed start destination
 <— Fragment NavDestination <- NavDestination ID
 
 
 <— A NavAction in NavDirections (Local) <- NavAction ID
 <| Transition
 | Animations
 | of NavAction
 |

Slide 24

Slide 24 text

NavGraph (2/2) <— Activity NavDestination
 
 
 <— A field of NavArgs
 
 
 
 
 // Nested NavGraph
 
 <— A NavAction for NavDirections (Global)

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

NavHost • NavController 제공하는 컨테이너 • NavHostFragment라는 구현체를 기본 제공 • Fragment 계층 구조:
 
 MainActivity • NavHostFragment • SplashFragment • LoginFragment • …

Slide 27

Slide 27 text

NavHost ũ app:defaultNavHost="true" // For Kotlin val hostFragment = NavHostFragment.create(R.navigation.nav_graph) supportFragmentManager.beginTransaction() .replace(R.id.nav_host, hostFragment) .setPrimaryNavigationFragment(hostFragment) .commit()

Slide 28

Slide 28 text

Futhermore..

Slide 29

Slide 29 text

못다한 얘기들 • 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

Slide 30

Slide 30 text

Sample Application Link: https://github.com/fornewid/GDGAndroid-atPangyo-2019-Navigation-Sample • Activity, Fragment 만을 사용 • 탐색 UX는 Medium 앱을 참고

Slide 31

Slide 31 text

Version Info

Slide 32

Slide 32 text

Version Rule Link: https://twitter.com/ianhlake/status/1103372174277013504

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

Conclusion • 화면 탐색을 다루는 '공식적인' 방법 + 1 • 직접적인 FragmentTransaction 필요 X • 다수의 Fragments 관리가 필요한 경우, 고려해볼 것 • 다음/이전 화면으로의 자유로운 이동 기능 • 아쉬운 부분은 존재 (Ex. 이전 화면으로 결과 전달 불가능) • 사실상 AndroidX로 전환 필요

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

Thank You 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.