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

Navigating Android like a Pro

Navigating Android like a Pro

Ever since Google introduced Jetpack Navigation, there has been mixed reception on how to get it to work on the project we have or the projects we start. Navigation library had a lot of changes in recent times and it is almost stable and caters to most of our needs. In this talk, you would learn how to get it working for your apps from someone who tried it when it was first introduced and reverted back.

You will learn what new features are introduced in the Navigation 2.x and how to use them effectively in your apps. You will also learn about designing a single activity app and how to use Nested graphs. On the whole, when you leave the session, you will start loving fragments again and be ready to navigate your app like a Pro!

This talk was given at droidcon SanFrancisco 2019.

Avatar for Vivek Chanddru

Vivek Chanddru

November 26, 2019
Tweet

More Decks by Vivek Chanddru

Other Decks in Technology

Transcript

  1. The 1.0.0 Issues • 1.0.0 took an year to get

    stable. It is okay to take that long but as a developer I was very impatient • 2.0.0 was essentially the same framework with androidX migrations done • Nav components was not as stable or feature rich as it is now.
  2. viewModel scoped
 to navGraph <dialog> 
 destinations <deeplink> 
 navigations

    Custom 
 NavController Dynamic feature
 module navigation
  3. NavAction • A NavAction is a class that gets generated

    for each of the action that is created in the navigation graph of the application
  4. NavAction • A NavAction is a class that gets generated

    for each of the action that is created in the navigation graph of the application • NavAction holds the meta data of the action such as • Destination • Default Arguments (as a Bundle) • NavOptions (animations, back stack behaviour, launch mode etc)
  5. Global Actions • Typically, an action is a pathway from

    one destination to another • Global Actions are actions that can be accessed from any destination to navigate to a particular destination • Useful where you want to create an action which can be used to launch the home screen or settings screen of the app from any other screen
  6. SafeArgs • Creates type-safe Args class which can be used

    to pass data to destinations • <DESTINATION>Directions class is generated with a method for each action from that destination • <DESTINATION>Args is created for the destination class which can populate the data using the fromBundle() method
  7. Explicit Deep Link • Used in cases where you want

    to expose the destinations through PendingIntent. • Used for Notifications, App Shortcuts, Widgets etc
  8. Explicit Deep Link • If the context passed to the

    NavDeepLinkBuilder is not an activity, then the Navigation Component queries the PackageManager for the launch intent for the activity • You can also get NavDeepLinkBuilder if you have a NavController instance already using NavController.createDeepLink()
  9. Implicit Deep Link • Used in cases where you want

    to open a destination using an URI • When another app invokes ACTION_OPEN on this URI, OS allows you to handle the URI with your app if it is available • Handles the back stack based on whether the Intent.FLAG_ACTIVITY_NEW_TASK flag is set or not
  10. <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application ... > <activity

    name=".MainActivity" ...> ... <nav-graph android:value="@navigation/nav_graph" /> ... </activity> </application> </manifest>
  11. NavController - NavHost • Navigation to a destination is done

    using a NavController • NavController is responsible for the navigation that happens within each NavHost • Each NavHost would have a NavController • Navigation to a destination can be done by obtaining an instance of NavController and using the navigate() method
  12. popUpTo & popUpToInclusive • Remove additional destinations from back stack

    using popUpTo and popUpToInclusive attributes on an <action>
  13. popUpTo & popUpToInclusive • Remove additional destinations from back stack

    using popUpTo and popUpToInclusive attributes on an <action> • app:popUpTo is used to navigate some destinations up to a certain specified destination during a navigate() call
  14. popUpTo & popUpToInclusive • Remove additional destinations from back stack

    using popUpTo and popUpToInclusive attributes on an <action> • app:popUpTo is used to navigate some destinations up to a certain specified destination during a navigate() call • app:popUpToInclusive is a boolean flag used to remove the duplicate destinations present when app:popUpTo is used
  15. popBackStack() • Use NavController.navigateUp() to navigate up the backstack •

    NavController.popBackStack() to pop the latest destination off the back stack
  16. popBackStack() • Use NavController.navigateUp() to navigate up the backstack •

    NavController.popBackStack() to pop the latest destination off the back stack • popBackStack() returns true when successful and false when there is no destination to pop off to
  17. Custom Back Navigation • OnBackPressedDispatcher from ComponentActivity • Add an

    OnBackPressedCallback callback to the dispatcher and handle back stack using handleOnBackPressed() method
  18. Custom Back Navigation • OnBackPressedDispatcher from ComponentActivity • Add an

    OnBackPressedCallback callback to the dispatcher and handle back stack using handleOnBackPressed() method • It is lifecycle aware
  19. Custom Back Navigation • OnBackPressedDispatcher from ComponentActivity • Add an

    OnBackPressedCallback callback to the dispatcher and handle back stack using handleOnBackPressed() method • It is lifecycle aware • Event is passed based on the order of adding callbacks
  20. Custom Back Navigation • OnBackPressedDispatcher from ComponentActivity • Add an

    OnBackPressedCallback callback to the dispatcher and handle back stack using handleOnBackPressed() method • It is lifecycle aware • Event is passed based on the order of adding callbacks • Event is passed down if the previous callback was not enabled
  21. Nested Graph • Useful to reuse a piece of flow

    within the app • They encapsulate the destinations and need a start destination • Select destinations and right-click and select “Move to Nested Graph”
  22. <!-- nav_graph of the app module --> <navigation ...> <fragment

    android:id="@+id/homeScreen"...> <action android:id="@+id/action_open_login_flow" app:destination="@id/login_flow_graph" /> </fragment> <include app:graph="@navigation/login_graph" /> </navigation> <!-- login_graph from different module --> <navigation android:id="@+id/login_flow_graph"...> ... </navigation>
  23. <!-- nav_graph of the app module --> <navigation ...> <fragment

    android:id="@+id/homeScreen"...> <action android:id="@+id/action_open_login_flow" app:destination="@id/login_flow_graph" /> </fragment> <include app:graph="@navigation/login_graph" /> </navigation> <!-- login_graph from different module --> <navigation android:id=“@+id/login_flow_graph”...> ... </navigation>
  24. <!-- nav_graph of the app module --> <navigation ...> <fragment

    android:id="@+id/homeScreen"...> <action android:id="@+id/action_open_login_flow" app:destination="@id/login_flow_graph" /> </fragment> <include app:graph="@navigation/login_graph" /> </navigation> <!-- login_graph from different module --> <navigation android:id="@+id/login_flow_graph"...> ... </navigation>
  25. repositories { maven { url "https://ci.android.com/builds/submitted/5956592/androidx_snapshot/ latest/repository/" } ... }

    dependencies { implementation "androidx.navigation:navigation-dynamic-features-fragment: 2.3.0-SNAPSHOT" }
  26. Using Dynamic Feature Navigator • Replace all instance of NavHostFragment

    with DynamicNavHostFragment • Add app:moduleName to any destination from the dynamic feature module
  27. Using Dynamic Feature Navigator • Replace all instance of NavHostFragment

    with DynamicNavHostFragment • Add app:moduleName to any destination from the dynamic feature module • Navigator library takes care of downloading the feature when the user navigates to that screen
  28. Using Dynamic Feature Navigator • Replace all instance of NavHostFragment

    with DynamicNavHostFragment • Add app:moduleName to any destination from the dynamic feature module • Navigator library takes care of downloading the feature when the user navigates to that screen • The download progress fragment can be customized
  29. Using Dynamic Feature Navigator • Replace all instance of NavHostFragment

    with DynamicNavHostFragment • Add app:moduleName to any destination from the dynamic feature module • Navigator library takes care of downloading the feature when the user navigates to that screen • The download progress fragment can be customized • Use DynamicInstallMonitor to monitor the status of download
  30. Listening to Navigation Changes navController.addOnDestinationChangedListener { _, destination, _ ->

    when(destination.id) { //do something based on the current destination } }
  31. val viewModel: MyViewModel by navGraphViewModels(R.id.nav_graph) { factory } ViewModelStoreOwner owner

    = controller.getViewModelStoreOwner(R.id.nav_graph); MyViewModel viewModel = new ViewModelProvider(owner, factory); Java Kotlin
  32. What Could Be Improved? • ViewPager support • Passing information

    back when doing pop operations on stack • Deep link support for dynamic features module (in 2.3.0)