0% found this document useful (0 votes)
137 views

Update UI Components With NavigationUI

NavigationUI provides methods to automatically update top app bars like toolbars and collapsing toolbars when navigating between destinations in an app. It handles updating the title and navigation button. It also allows tying menu items to destinations so that selecting an item navigates to the corresponding destination fragment.

Uploaded by

Sanjay Patel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
137 views

Update UI Components With NavigationUI

NavigationUI provides methods to automatically update top app bars like toolbars and collapsing toolbars when navigating between destinations in an app. It handles updating the title and navigation button. It also allows tying menu items to destinations so that selecting an item navigates to the corresponding destination fragment.

Uploaded by

Sanjay Patel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Update UI components with NavigationUI

The Navigation component includes a NavigationUI class. This class contains static methods that manage navigation with the top
app bar, the navigation drawer, and bottom navigation.

Top app bar


The top app bar provides a consistent place along the top of your app for displaying information and actions from the current
screen.
Figure 1. A screen displaying a top app bar.

NavigationUI contains methods that automatically update content in your top app bar as users navigate through your app. For
example, NavigationUI uses the destination labels from your navigation graph to keep the title of the top app bar up-to-date.
<navigation>
<fragment ...
android:label="Page title">
...
</fragment>
</navigation>

When using NavigationUI with the top app bar implementations discussed below, the label you attach to destinations can be
automatically populated from the arguments provided to the destination by using the format of {argName} in your label.

NavigationUI provides support for the following top app bar types:

 Toolbar

 CollapsingToolbarLayout

 ActionBar

For more information on app bars, see Set up the app bar.

AppBarConfiguration
NavigationUI uses an AppBarConfiguration object to manage the behavior of the Navigation button in the upper-left corner of
your app's display area. The Navigation button’s behavior changes depending on whether the user is at a top-level destination.

A top-level destination is the root, or highest level destination, in a set of hierarchically-related destinations. Top-level destinations
do not display an Up button in the top app bar because there is no higher level destination. By default, the start destination of your
app is the only top-level destination.
When the user is at a top-level destination, the Navigation button becomes a drawer icon if the destination uses
a DrawerLayout. If the destination doesn't use a DrawerLayout, the Navigation button is hidden. When the user is on any other

destination, the Navigation button appears as an Up button . To configure the Navigation button using only the
start destination as the top-level destination, create an AppBarConfiguration object, and pass in the corresponding navigation
graph, as shown below:

KOTLINJAVA

val appBarConfiguration = AppBarConfiguration(navController.graph)

In some cases, you might need to define multiple top-level destinations instead of using the default start destination. Using
a BottomNavigationView is a common use case for this, where you may have sibling screens that are not hierarchically related to
each other and may each have their own set of related destinations. For cases like these, you can instead pass a set of destination
IDs to the constructor, as shown below:

KOTLINJAVA

val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.profile))


Create a Toolbar
To create a Toolbar with NavigationUI, first define the bar in your main activity, as shown below:

<LinearLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" />
<fragment
android:id="@+id/nav_host_fragment"
... />
...
</LinearLayout>

Next, call setupWithNavController() from your main activity's onCreate() method, as shown in the following example:

KOTLINJAVA

override fun onCreate(savedInstanceState: Bundle?) {


setContentView(R.layout.activity_main)

...

val navController = findNavController(R.id.nav_host_fragment)


val appBarConfiguration = AppBarConfiguration(navController.graph)
findViewById<Toolbar>(R.id.toolbar)
.setupWithNavController(navController, appBarConfiguration)
}
Note: When using a Toolbar, Navigation automatically handles click events for the Navigation button, so you do not need to
override onSupportNavigateUp().

Include CollapsingToolbarLayout
To include a CollapsingToolbarLayout with your Toolbar, first define the Toolbar and surrounding layout in your activity, as
shown below:

<LinearLayout>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="@dimen/tall_toolbar_height">

<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="top"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="@+id/nav_host_fragment"
... />
...
</LinearLayout>

Next, call setupWithNavController() from your main activity's onCreate method, as shown below:

KOTLINJAVA

override fun onCreate(savedInstanceState: Bundle?) {


setContentView(R.layout.activity_main)

...

val layout = findViewById<CollapsingToolbarLayout>(R.id.collapsing_toolbar_layout)


val toolbar = findViewById<Toolbar>(R.id.toolbar)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
layout.setupWithNavController(toolbar, navController, appBarConfiguration)
}

Action bar
To add navigation support to the default action bar, call setupActionBarWithNavController() from your main
activity's onCreate() method, as shown below. Note that you need to declare your AppBarConfiguration outside of onCreate(),
since you also use it when overriding onSupportNavigateUp():
KOTLINJAVA

private lateinit var appBarConfiguration: AppBarConfiguration

...

override fun onCreate(savedInstanceState: Bundle?) {


...

val navController = findNavController(R.id.nav_host_fragment)


appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
}

Next, override onSupportNavigateUp() to handle Up navigation:

KOTLINJAVA

override fun onSupportNavigateUp(): Boolean {


val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
Support app bar variations
Adding the top app bar to your activity works well when the app bar’s layout is similar for each destination in your app. If, however,
your top app bar changes substantially across destinations, then consider removing the top app bar from your activity and defining
it in each destination fragment, instead.

As an example, one of your destinations may use a standard Toolbar, while another uses an AppBarLayout to create a more
complex app bar with tabs, as shown in figure 2.
Figure 2. Two app bar variations. On the left, a standard Toolbar. On the right, an AppBarLayout with a Toolbar and tabs.

To implement this example within your destination fragments using NavigationUI, first define the app bar in each of your fragment
layouts, beginning with the destination fragment that uses a standard toolbar:

<LinearLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
... />
...
</LinearLayout>

Next, define the destination fragment that uses an app bar with tabs:

<LinearLayout>
<com.google.android.material.appbar.AppBarLayout
... />

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
... />

<com.google.android.material.tabs.TabLayout
... />

</com.google.android.material.appbar.AppBarLayout>
...
</LinearLayout>
The navigation configuration logic is the same for both of these fragments, except that you should
call setupWithNavController() from within each fragment's onViewCreated() method, instead of initializing them from the
activity:

KOTLINJAVA

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {


val navController = findNavController()
val appBarConfiguration = AppBarConfiguration(navController.graph)

view.findViewById<Toolbar>(R.id.toolbar)
.setupWithNavController(navController, appBarConfiguration)
}

Note: Placing the top app bar into the destination fragment layout will result in the app bar animating with the rest of the layout during fragment
transitions when a fragment transition is set.

Tie destinations to menu items


NavigationUI also provides helpers for tying destinations to menu-driven UI components. NavigationUI contains a helper
method, onNavDestinationSelected(), which takes a MenuItem along with the NavController that hosts the associated
destination. If the id of the MenuItem matches the id of the destination, the NavController can then navigate to that destination.

As an example, the XML snippets below define a menu item and a destination with a common id, details_page_fragment:

<?xml version="1.0" encoding="utf-8"?>


<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
... >

...

<fragment android:id="@+id/details_page_fragment"
android:label="@string/details"
android:name="com.example.android.myapp.DetailsFragment" />
</navigation>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

...

<item
android:id="@id/details_page_fragment"
android:icon="@drawable/ic_details"
android:title="@string/details" />
</menu>

If your menu was added via the Activity's onCreateOptionsMenu(), for example, you can associate the menu items with
destinations by overriding the Activity's onOptionsItemSelected() to call onNavDestinationSelected(), as shown in the
following example:

KOTLINJAVA

override fun onOptionsItemSelected(item: MenuItem): Boolean {


val navController = findNavController(R.id.nav_host_fragment)
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}
Now, when a user clicks the details_page_fragment menu item, the app automatically navigates to the corresponding
destination with the same id.

Add a navigation drawer


The navigation drawer is a UI panel that shows your app's main navigation menu. The drawer appears when the user touches the

drawer icon in the app bar or when the user swipes a finger from the left edge of the screen.
navigation menu.

The drawer icon is displayed on all top-level destinations that use a DrawerLayout.

To add a navigation drawer, first declare a DrawerLayout as the root view. Inside the DrawerLayout, add a layout for the main UI
content and another view that contains the contents of the navigation drawer.

For example, the following layout uses a DrawerLayout with two child views: a NavHostFragment to contain the main content and
a NavigationView for the contents of the navigation drawer.

<?xml version="1.0" encoding="utf-8"?>


<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<fragment
android:name="androidx.navigation.fragment.NavHostFragment"
android:id="@+id/nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />

<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true" />

</androidx.drawerlayout.widget.DrawerLayout>

Next, connect the DrawerLayout to your navigation graph by passing it to AppBarConfiguration, as shown in the following
example:

KOTLINJAVA

val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

Note: When using NavigationUI, the top app bar helpers automatically transition between the drawer icon and the Up icon as the current
destination changes. You don't need to use ActionBarDrawerToggle.

Next, in your main activity class, call setupWithNavController() from your main activity's onCreate() method, as shown below:

KOTLINJAVA

override fun onCreate(savedInstanceState: Bundle?) {


setContentView(R.layout.activity_main)

...

val navController = findNavController(R.id.nav_host_fragment)


findViewById<NavigationView>(R.id.nav_view)
.setupWithNavController(navController)
}

Note: Setting up the navigation drawer requires that you also set up your navigation graph and menu xml as described in Tie destinations to
menu items.

Bottom navigation
NavigationUI can also handle bottom navigation. When a user selects a menu item,
the NavController calls onNavDestinationSelected() and automatically updates the selected item in the bottom navigation
bar.
Figure 4. A bottom navigation bar.

To create a bottom navigation bar in your app, first define the bar in your main activity, as shown below:
<LinearLayout>
...
<fragment
android:id="@+id/nav_host_fragment"
... />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
app:menu="@menu/menu_bottom_nav" />
</LinearLayout>

Next, in your main activity class, call setupWithNavController() from your main activity's onCreate() method, as shown below:

KOTLINJAVA

override fun onCreate(savedInstanceState: Bundle?) {


setContentView(R.layout.activity_main)

...

val navController = findNavController(R.id.nav_host_fragment)


findViewById<BottomNavigationView>(R.id.bottom_nav)
.setupWithNavController(navController)
}

Note: Setting up bottom navigation requires that you also set up your navigation graph and menu xml as described in Tie destinations to menu
items.

For a comprehensive example that includes bottom navigation, see the Android Architecture Components Advanced Navigation
Sample on GitHub.
Listen for navigation events
Interacting with the NavController is the primary method for navigating between destinations. The NavController is responsible
for replacing the contents of the NavHost with the new destination. In many cases, UI elements—such as a top app bar or other
persistent navigation controls like a BottomNavigationBar—live outside of the NavHost and need to be updated as you navigate
between destinations.

NavController offers an OnDestinationChangedListener interface that is called when the NavController's current
destination or its arguments change. A new listener can be registered via the addOnDestinationChangedListener() method.
Note that when calling addOnDestinationChangedListener(), if the current destination exists, it's immediately sent to your
listener.

NavigationUI uses OnDestinationChangedListener to make these common UI components navigation-aware. Note, however,
that you can also use OnDestinationChangedListener on its own to make any custom UI or business logic aware of navigation
events.

As an example, you might have common UI elements that you intend to show in some areas of your app while hiding them in
others. Using your own OnDestinationChangedListener, you can selectively show or hide these UI elements based on the target
destination

You might also like