Jetpack Navigation 02

Dmitry Klokov·2021년 3월 17일
0

ANDROID-KOTLIN-FUNDAMENTALS

목록 보기
19/19
post-thumbnail

Prev | Jetpack Navigation 01

1. Navigating using menus, drawers and bottom navigation


The Navigation Components include a NavigationUI class and navigation-us-ktx kotlin extensions. NavigationUI has static methods that associate menu items with navigation destinations, and navigation-ui-ktx is a set of extenstion functions that do the same. If NavigationUI finds a menu item with the same ID as a destination on the current graph, it configures the menu item to navigate to that destination.

Using NavigationUI with an Options menu

One of the easiest ways to use NavigationUI is to have it simplify option menu setup. In particular, NavigationUI simplifies handling the onOptionsItemSelected callback.

  1. Open MainActivity.kt
    Notice how you already have the code for inflating the menu overflow_menu in onCreateOptionsMenu

    MainActivity.kt

  2. Open res/menu/overflow_menu.xml

  3. Update your overflow menu to include the settings_dest

    overflow_menu.xml

  4. Open MainActivity.kt

  5. Have NavigationUI handle onOptionsItemSelected with the onNavDestinationSelected helper method. If the menu item is not meant to navigate, handle with super.onOptionsItemSelected

    MainActivity.kt

  6. Run your app. You should have a functional ActionBar menu that navigates to the SettingsFragment.

Using NavigationUI to configure Bottom Navigation

The coded already contains the XML layout code for implementing bottom navigation, which is why you see the bottom navigation bar. But it doesn't navigate anywhere.

  1. Open res/layout/navigation_activity.xml (h470dp) and click the Text tab
    Notice how the XML layout code for bottom navigation is there and refers to bottom_nav_menu.xml

  2. Open res/menu/bottom_nav_menu.xml
    Notice how there are two items for bottom navigation and that their ids match the destinations of navigation graph destinations:

    bottom_nav_menu.xml

    Let's make the bottom navigation actually do something using NavigationUI.

  3. Open MainActivity.kt

  4. Implement the setupBottomNavMenu method using setupWithNavController(bottomNavigationView: BottomNavigationView, navController: NavController)

    MainActivity.kt

Now your bottom navigation works!

Using NavigationUI to configure a Navigation Drawer

Finally, let's use NavigationUI to configure the side navigation and navigation drawer, including handling the ActionBar and proper up navigation. You'll see this if you've got a large enough screen or if the screen's too short for bottom navigation.

First observe how the proper layout XML code is already in the app.

  1. Open both navigation_activity.xml and navigation_activity.xml (w960dp)

    Notice how both layouts contain a NavigationView connected to nav_drawer_menu. In the tablet version (w960dp) the NavigationView is always on screen. On smaller devices the NavigationView is nested within a DrawerLayout.

    Now to start implementing the NavigationView navigation.

  2. Open MainActivity.kt

  3. Implement the setupNavigationMenu method using setupWithNavController(navigationView: NavigationView, navController: NavController). Notice how this version of the method takes a NavigationView and not a BottomNavigationView.

    MainActivity.kt

    Now the navigation view menu will show on the screen, but it will not affect the ActionBar.

    Setting up the ActionBar requires creating an instance of AppBarConfiguration. The purpose of AppBarConfiguration is to specify the configuration options you want for your toolbars, collapsing toolbars, and action bars. Configuration options include whether the bar must handle a drawer layout and which destinations are considered top-level destinations.

    Top-level destinations are the root-level destinations of your app. These destinations do not display an "up" button in the app bar, and they display the drawer icon if the destination uses a drawer layout.


  1. Create an AppBarConfiguration by passing in a set of top-level destination IDs and the drawer layout.

    MainActivity.kt

    How to determine top-level destinations

    Destinations reachable via global navigation UI, such as bottom nav or side nav, all appear to users as on the same top level of the hierarchy. Therefore, they are top level destinations. home_dest and deeplink_dest are in the bottom nav and we want the drawer icon to show on both of these destinations, so they are top-level destinations.

    Note that the start destination is always considered a top-level destination. If you don't specify a list of top-level destinations, then the only top-level destination is your start destination. You can learn more about AppBarConfiguration in the documentation.

    Now that you have an AppBarConfiguration, you can call NavigationUI.setupActionBarWithNavController. This will do the following:

    • Show a title in the ActionBar based off of the destination's label
    • Display the Up button whenever you're not on a top-level destination
    • Display a drawer icon (hamburger icon) when you're on a top-level destination
  2. Implement setupActionBarWithNavController

    MainActivity.kt

    You should also have NavigationUI handle what happens when the Up button is pressed.

  1. Override onSupportNavigateUp and call NavigationUI.navigateUp, using the same AppBarConfiguration.

    MainActivity.kt

  1. Run your code. If you open the app in split screen, you should have a working navigation drawer. The up icon and the drawer icon should display at the appropriate times and work correctly.

    Notice

    The layout navigation_activity.xml (h470dp) will be used on phones in portrait mode. This layout does not include the navigation drawer and instead includes the bottom navigation, which is why you should open the app in split screen to see the navigation drawer. The reason there is not a layout with both a navigation drawer and bottom navigation is because Material Design guidelines cautions against this.

    Adding new destinations to a NavigationView is easy. Once you have the navigation drawer working with up and back navigation, you just need to add the new menu item.

  2. Open menu/nav_drawer_menu.xml

  3. Add a new menu item for setting_dest

    Now your navigation drawers shows the Settings screen as a destination.

2. Deep Linking to a destination


Navigation components also include deep link support. Deep links are a way to jump into the middle of your app's navigation, whether that's from an actual URL link or a pending intent from a notification.

One benefit of using the navigation library to handle deep links is that it ensures users start on the right destination with the appropriate back stack from other entry points such as app widgets, notifications, or web links (covered in the next step).

Navigation provides a NavDeepLinkBuilder class to construct a PendingIntent that will take the user to a specific destination.

We'll use the NavDeepLinkBuilder to hook up an app widget to a destination.

  1. Open DeepLinkAppWidgetProvider.kt

  2. Add a PendingIntent constructed with NavDeepLinkBuilder:

    DeepLinkAppWidgetProvider.kt

    Notice:

    • setGraph includes the navigation graph.
    • setDestination specifies where the link goes to.

    • setArguments includes any arguments you want to pass into your deep link.

      By default NavDeepLinkBuilder will start your launcher Activity. You can override this behavior by passing in an activity as the context or set an explicit activity class via setComponentName().

  3. Add the Deep Link widget to your home screen.

  1. Tap the widget, and verify that the Android destination opens with the correct argument. It should say "From Widget" at the top since that is the argument you passed in DeepLinkAppWidgetProvider.

  1. Verify that hitting the back button takes you to the home_dest destination.

As a convenience, you can also call NavController's createDeepLink() method to use the Context and current navigation graph from the NavController.

The backstack for a deep link is determined using the navigation graph you pass in. If the explicit Activity you've chosen has a parent activity, those parent Activities are also included.

The backstack is generated using the destinations specified with app:startDestination. In this app we only have one activity and one level of navigation, so the backstack will take you to the home_dest destination.

More complicated navigation can include nested navigation graphs. The app:startDestination at each level of the nested graphs determines the backstack. For more information on deep links and nested graphs, check out the Principles of Navigation.


One of the most common uses of a deep link is to allow a web link to open an activity in your app. Traditionally you would use an intent-filter and associate a URL with the activity you want to open.

The navigation library makes this extremely simple and allows you to map URLs directly to destinations in your navigation graph.

<deepLink> is an element you can add to a destination in your graph. Each <deepLink> element has a single required attribute: app:uri.

In addition to a direct URI match, the following features are supported:

  • URIs without a scheme are assumed to be http and https. For example, www.example.com will match http://www.example.com and https://www.example.com.

  • You can use placeholders in the form of {placeholder_name} to match one or more characters. The String value of the placeholder is available in the arguments Bundle which has a key of the same name. For example, http://www.example.com/users/{id} will match http://www.example.com/users/4.

  • You can use the .* wildcard to match zero or more characters.

  • NavController will automatically handle ACTION_VIEW intents and look for matching deep links.

In this step, you'll add a deep link to www.example.com

  1. Open mobile_navigation.xml

  2. Add a <deepLink> element to the deeplink_dest destination.

    mobile_navigation.xml

  3. Open AndroidManifest.xml

  4. Add the nav-graph tag. This will ensure the appropriate intent filter is generated

    AndroidManifest.xml

  5. Launch your app using a deep link. There are two ways to do this:

    • Use adb :

    • Navigate via the Google app. You should be able to put www.example.com/urlTest in the search bar and the disambiguation window will appear. Select Navigation codelab

      Either way, you should see the message "urlTest" on screen. This was passed through to the fragment, from the URL.


Learn more | Google Codelabs

profile
Power Weekend

0개의 댓글