This codelab is part of the Android Kotlin Fundamentals course. You'll get the most value out of this course if you work through the codelabs in sequence. All the course codelabs are listed on the Android Kotlin Fundamentals codelabs landing page.
In the previous codelab, you modified the AndroidTrivia app to add a fragment to an existing activity. In this codelab, you add navigation to the app.
Structuring the user's experience of navigating through an app has always been an interesting topic for developers. For Android apps, the Navigation Architecture Component makes it easier to implement navigation.
A destination is any place inside the app to which a user can navigate. A navigation graph for an app consists of a set of destinations within the app. Navigation graphs allow you to visually define and customize how users navigate among destinations in your app.
The AndroidTrivia app, which you started working on in the previous codelab, is a game in which users answer questions about Android development. If the user answers three questions correctly, they win the game.
If you completed the previous codelab, use that code as the starter code for this codelab. Otherwise, download the AndroidTriviaFragment file to get the starter code.
In this codelab, you update the AndroidTrivia app in the following ways:
To use the navigation library, you need to add the navigation dependencies to your Gradle files.
build.gradle
file, along with the other ext
variables, add a variable for the navigationVersion
. To find the latest navigation version number, see Declaring dependencies in the Android developer documentation.ext {
...
navigationVersion = '1.0.0-rc02'
...
}
navigation-fragment-ktx
and navigation-ui-ktx
, as shown below:dependencies {
...
implementation"android.arch.navigation:navigation-fragment-ktx:$navigationVersion"
implementation "android.arch.navigation:navigation-ui-ktx:$navigationVersion"
...
}
A navigation host fragment acts as a host for the fragments in a navigation graph. The navigation host fragment is usually named NavHostFragment
.
As the user moves between destinations defined in the navigation graph, the navigation host fragment swaps fragments in and out as necessary. The fragment also creates and manages the appropriate fragment back stack.
In this task, you modify your code to replace the TitleFragment
with the NavHostFragment
.
activity_main.xml
file, change the name of the existing title fragment to androidx.navigation.fragment.NavHostFragment
.myNavHostFragment
.app:navGraph
attribute and set it to the navigation graph resource, which is @navigation/navigation
.app:defaultNavHost
attribute and set it to "true"
. Now this navigation host is the default host and will intercept the system Back button.Inside the activity_main.xml
layout file, your fragment
now looks like the following:
<!-- The NavHostFragment within the activity_main layout -->
<fragment
android:id="@+id/myNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/navigation"
app:defaultNavHost="true" />
In this task, you add the title fragment and the game fragment to the app's navigation graph. You connect the fragments to each other. Then you add a click handler to the Play button so that the user can navigate from the title screen to the game screen.
TitleFragment
fragment is where app users start when they first open the app.fragment
element for the gameFragment
includes tools:layout="@layout/fragment_game"
, as shown below.<!-- The game fragment within the navigation XML, complete with tools:layout. -->
<fragment
android:id="@+id/gameFragment"
android:name="com.example.android.navigation.GameFragment"
android:label="GameFragment"
tools:layout="@layout/fragment_game" />
action_titleFragment_to_gameFragment
.The title fragment is connected to the game fragment by an action. Now you want the Play button on the title screen to navigate the user to the game screen.
TitleFragment.kt
file. Inside the onCreateView()
method, add the following code before the return
statement:binding.playButton.setOnClickListener{}
setOnClickListener
, add code to access the Play button through the binding class and navigate to the game fragment://The complete onClickListener with Navigation
binding.playButton.setOnClickListener { view : View ->
view.findNavController().navigate(R.id.action_titleFragment_to_gameFragment)
}
TitleFragment.kt
file:import androidx.navigation.findNavController
In this step, you add conditional navigation, which is navigation that's only available to the user in certain contexts. A common use case for conditional navigation is when an app has a different flow, depending on whether the user is logged in.
Your app is a different case: Your app will navigate to a different fragment, based on whether the user answers all the questions correctly.
The starter code contains two fragments for you to use in your conditional navigation:
GameWonFragment
takes the user to a screen that shows a "Congratulations!" message.GameOverFragment
takes the user to a screen that shows a "Try Again" message.navigation.xml
file, which is in the navigation
folder.gameOverFragment
.gameWonFragment
.The Layout Editor now looks something like the following screenshot:
In this step, you connect the game fragment to both the game-won fragment and the game-over fragment.
GameFragment
is a fragment class that contains questions and answers for the game. The class also includes logic that determines whether the user wins or loses the game. You need to add conditional navigation in the GameFragment
class, depending on whether the player wins or loses.
GameFragment.kt
file. The onCreateView()
method defines an if
/ else
condition that determines whether the player has won or lost: binding.submitButton.setOnClickListener @Suppress("UNUSED_ANONYMOUS_PARAMETER")
{
...
// answer matches, we have the correct answer.
if (answers[answerIndex] == currentQuestion.answers[0]) {
questionIndex++
// Advance to the next question
if (questionIndex < numQuestions) {
currentQuestion = questions[questionIndex]
setQuestion()
binding.invalidateAll()
} else {
// We've won! Navigate to the gameWonFragment.
}
} else {
// Game over! A wrong answer sends us to the gameOverFragment.
}
}
}
else
condition for winning the game, add the following code, which navigates to the gameWonFragment
. Make sure that the action name (action_gameFragment_to_gameWonFragment
in this example) exactly matches what's set in the navigation.xml
file. // We've won! Navigate to the gameWonFragment.
view.findNavController()
.navigate(R.id.action_gameFragment_to_gameWonFragment)
else
condition for losing the game, add the following code, which navigates to the gameOverFragment
:// Game over! A wrong answer sends us to the gameOverFragment.
view.findNavController().
navigate(R.id.action_gameFragment_to_gameOverFragment)
GameWonFragment
. GameOverFragment
.The Android system's Back button is shown as 1 in the screenshot above. If the user presses the Back button in the game-won fragment or the game-over fragment, the app navigates to the question screen. Ideally, the Back button should navigate back to the app's title screen. You change the destination for the Back button in the next task.
The Android system keeps track of where users navigate on an Android-powered device. Each time the user goes to a new destination on the device, Android adds that destination to the back stack.
When the user presses the Back button, the app goes to the destination that's at the top of the back stack. By default, the top of the back stack is the screen that the user last viewed. The Back button is typically the left-most button at the bottom of the screen, as shown below. (The Back button's exact appearance is different on different devices.)
Until now, you've let the navigation controller handle the back stack for you. When the user navigates to a destination in your app, Android adds this destination to the back stack.
In the AndroidTrivia app, when the user presses the Back button from the GameOverFragment
or GameWonFragment
screen, they end up back in the GameFragment
. But you don't want to send the user to the GameFragment
, because the game is over. The user could restart the game, but a better experience would be to find themselves back at the title screen.
A navigation action can modify the back stack. In this task, you change the action that navigates from the game fragment so that the action removes the GameFragment
from the back stack. When the user wins or loses the game, if they press the Back button, the app skips the GameFragment
and goes back to the TitleFragment
.
In this step, you manage the back stack so that when the user is at the GameWon
or GameOver
screen, pressing the Back button returns them to the title screen. You manage the back stack by setting the "pop" behavior for the actions that connect the fragments:
popUpTo
attribute of an action "pops up" the back stack to a given destination before navigating. (Destinations are removed from the back stack.)popUpToInclusive
attribute is false
or is not set, popUpTo
removes destinations up to the specified destination, but leaves the specified destination in the back stack.popUpToInclusive
is set to true
, the popUpTo
attribute removes all destinations up to and including the given destination from the back stack. popUpToInclusive
is true
and popUpTo
is set to the app's starting location, the action removes all app destinations from the back stack. The Back button takes the user all the way out of the app.In this step, you set the popUpTo
attribute for the two actions that you created in the previous task. You do this using the Pop To field in the Attributes pane of the Layout Editor.
navigation.xml
in the res > navigation folder. If the navigation graph does not appear in the layout editor, click the Design tab.gameFragment
to the gameOverFragment
. (In the preview area, the action is represented by a blue line that connects the two fragments.)gameFragment
. Select the Inclusive checkbox.popUpTo
and popUpToInclusive
attributes in the XML. The attributes tell the navigation component to remove fragments from the back stack up to and including GameFragment
. (This has the same effect as setting the Pop To field to titleFragment
and clearing the Inclusive checkbox.)gameFragment
to the gameWonFragment
. Again, set Pop To to gameFragment
in the Attributes pane and select the Inclusive checkbox.TitleFragment
.Your app currently has the following user flow:
GameWon
or GameOver
screen.TitleFragment
. (You implemented this behavior in Step 1 of this task, above.)In this step you implement two more steps of user flow:
GameFragment
screen.TitleFragment
screen (instead of back to the GameWon
or GameOver
screen). To create this user flow, use the PopUpTo
attribute to manage the back stack:
navigation.xml
file, add a navigation action connecting gameOverFragment
to gameFragment
. Make sure that the fragment names in the action's ID match the fragment names that are in the XML. For example, the action ID might be action_gameOverFragment_to_gameFragment
.titleFragment
. titleFragment
to be included in the destinations that are removed from the back stack. Instead, you want everything up to the TitleFragment
(but not including it) to be removed from the back stack.navigation.xml
file, add a navigation action connecting gameWonFragment
to gameFragment
.titleFragment
and clear the Inclusive checkbox.Now add functionality to the Try Again and Next Match buttons. When the user taps either button, you want the app to navigate to the GameFragment
screen so that the user can try the game again.
GameOverFragment.kt
Kotlin file. At the end of the onCreateView()
method, before the return
statement, add the following code. The code adds a click listener to the Try Again button. When the user taps the button, the app navigates to the game fragment.// Add OnClick Handler for Try Again button
binding.tryAgainButton.setOnClickListener{view: View->
view.findNavController()
.navigate(R.id.action_gameOverFragment_to_gameFragment)}
GameWonFragment.kt
Kotlin file. At the end of the onCreateView()
method, before the return
statement, add the following code:// Add OnClick Handler for Next Match button
binding.nextMatchButton.setOnClickListener{view: View->
view.findNavController()
.navigate(R.id.action_gameWonFragment_to_gameFragment)}
The app bar, sometimes called the action bar, is a dedicated space for app branding and identity. For example, you can set the app bar's color. The app bar gives the user access to familiar navigation features such as an options menu. To access the options menu from the app bar, the user taps the icon with the three vertical dots .
The app bar displays a title string that can change with each screen. For the title screen of the AndroidTrivia app, the app bar displays "Android Trivia." On the question screen, the title string also shows which question the user is on ("1/3," "2/3," or "3/3.")
Currently in your app, the user uses the system Back button to navigate to previous screens. However, Android apps can also have an on-screen Up button that appears at the top left of the app bar.
In the AndroidTrivia app, you want the Up button to appear on every screen except the title screen. The Up button should disappear when the user reaches the title screen, because the title screen is at the top of the app's screen hierarchy.
The navigation components includes a UI library called NavigationUI
. The navigation controller integrates with the app bar to implement the behavior of the Up button, so you don't have to do it yourself.
In the following steps, you use the navigation controller to add an Up button to your app:
MainActivity.kt
kotlin file. Inside the onCreate()
method, add code to find the navigation controller object:val navController = this.findNavController(R.id.myNavHostFragment)
onCreate()
method, add code to link the navigation controller to the app bar:NavigationUI.setupActionBarWithNavController(this,navController)
onCreate()
method, override the onSupportNavigateUp()
method to call navigateUp()
in the navigation controller:override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return navController.navigateUp()
}
Android has different types of menus, including the options menu. On modern Android devices, the user accesses the options menu by tapping three vertical dots that appear in the app bar.
In this task, you add an About menu item to the options menu. When the user taps the About menu item, the app navigates to the AboutFragment
, and the user sees information about how to use the app.
navigation.xml
file and click the Design tab to see the navigation graph.ID
is aboutFragment
.options_menu.xml
file from the res > menu folder and click the Design tab to see the Layout Editor.In this step, you add code to implement behavior when the user taps the About menu item.
TitleFragment.kt
Kotlin file. Inside the onCreateView()
method, before the return
, call the setHasOptionsMenu()
method and pass in true
.override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
...
setHasOptionsMenu(true)
return binding.root
}
onCreateView()
method, override the onCreateOptionsMenu()
method. In the method, add the options menu and inflate the menu resource file.override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
inflater?.inflate(R.menu.options_menu, menu)
}
onOptionsItemSelected()
method to take the appropriate action when the menu item is tapped. In this case, the action is to navigate to the fragment that has the same id
as the selected menu item. override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return NavigationUI.onNavDestinationSelected(item!!,
view!!.findNavController())
|| super.onOptionsItemSelected(item)
}
import android.view.*
to resolve several references (and replace more specific imports such as import android.view.ViewGroup
).In this task, you add a navigation drawer to the AndroidTrivia app. The navigation drawer is a panel that slides out from the edge of the screen. The drawer typically contains a header and a menu.
On phone-sized devices, the navigation drawer is hidden when not in use. Two types of user actions can make the navigation drawer appear:
The screenshot below shows an open navigation drawer.
The navigation drawer is part of the Material Components for Android library, or Material library. You use the Material library to implement patterns that are part of Google's Material Design guidelines.
In your AndroidTrivia app, the navigation drawer will contain two menu items. The first item points to the existing "about" fragment, and the second item will point to a new "rules" fragment.
dependencies {
...
implementation "com.google.android.material:material:$supportlibVersion"
...
}
The navigation drawer will have two menu items, each representing a fragment that can be reached from the navigation drawer. Both destinations must have an ID in the navigation graph.
The AboutFragment
already has an ID
in the navigation graph, but the RulesFragment
does not, so add it now:
fragment_rules.xml
layout file to see what it looks like. Click the Design tab to look at the preview in the design editor.navigation.xml
file in the Navigation Editor. Click the New Destination button and add the rules fragment. Set its ID to rulesFragment.
To create a navigation drawer, you create the navigation menu. You also need to put your views inside a DrawerLayout
in the layout file.
activity_main.xml
layout file. To get all the drawer functionality for free, put your views inside a DrawerLayout
. Wrap the entire <LinearLayout>
inside a <DrawerLayout>
. (In other words, add a DrawerLayout
as the root view.)<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
. . .
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>
NavigationView
that uses the navdrawer_menu
that you just defined. Add the following code in the DrawerLayout
, after the </LinearLayout>
element:<com.google.android.material.navigation.NavigationView
android:id="@+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:menu="@menu/navdrawer_menu" />
You created the menu items for the navigation drawer and the navigation drawer layout. Now you need to connect the navigation drawer to the navigation controller so that when users select items in the navigation drawer, the app navigates to the appropriate fragment.
Mainactivity.kt
Kotlin file. In onCreate()
, add the code that allows the user to display the navigation drawer. Do this by calling setupWithNavController()
. Add the following code at the bottom of onCreate()
:NavigationUI.setupWithNavController(binding.navView, navController)
Although the navigation drawer works, you need to fix one more thing. Typically apps also allow users to display the navigation drawer by tapping the drawer button (three lines) in the app bar on the home screen. Your app does not yet display the drawer button on the home screen.
The final step is to enable the user to access the navigation drawer from the drawer button at the top left of the app bar.
Mainactivity.kt
Kotlin file, add the lateinit
drawerLayout
member variable to represent the drawer layout: private lateinit var drawerLayout: DrawerLayout
onCreate()
method, initialize drawerLayout
, after the binding
variable has been initialized. val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,
R.layout.activity_main)
drawerLayout = binding.drawerLayout
drawerLayout
as the third parameter to the setupActionBarWithNavController()
method:NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
onSupportNavigateUp()
method to return NavigationUI
.navigateUp
instead of returning navController
.navigateUp
. Pass the navigation controller and the drawer layout to navigateUp()
. The method will look like as follows:override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return NavigationUI.navigateUp(navController, drawerLayout)
}
import androidx.drawerlayout.widget.DrawerLayout
You have now added several different navigation options to your app.
The user can now progress through the app by playing the game. They can get back to the home screen at any time by using the Up button. They can get to the About screen either from the Options menu or from the navigation drawer. Pressing the Back button takes them back through previous screens in a way that makes sense for the app. The user can open the navigation drawer by swiping in from the left on any screen, or by tapping the drawer button in the app bar on the home screen.
Your app includes robust, logical navigation paths that are intuitive for your user to use. Congratulations!
Android Studio project: AndroidTriviaNavigation
To use the Android navigation library, you need to do some setup:
navigation-fragment-ktx
and navigation-ui-ktx
in the module-level build.gradle
file.ext
variable for the navigationVersion
in the project-level build.gradle
file.Navigation destinations are fragments, activities, or other app components that the user navigates to. A navigation graph defines the possible paths from one navigation destination to the next.
res/navigation
folder, and it's typically called navigation.xml
.navigation.xml
file and click the Design tab.navigation.xml
file, each of these connections is represented as an action
that has an ID
. A navigation host fragment, usually named NavHostFragment
, acts as a host for the fragments in the navigation graph:
NavHostFragment
swaps the fragments in and out and manages the fragment back stack.activity_main.xml
layout file, the NavHostFragment
is represented by a fragment
element with the name android:name="androidx.navigation.fragment.NavHostFragment"
.To define which fragment is displayed when the user taps a view (for example a button), set the onClick
listener for the view:
onClick
listener, call findNavController().navigate()
on the view.ID
of the action
that leads to the destination.Conditional navigation navigates to one screen in one case, and to a different screen in another case. To create conditional navigation:
View
, add code to detect the conditions. Then call findNavController().navigate()
on the view, passing in the ID for the appropriate action.The system's Back button is usually at the bottom of the device. By default, the Back button navigates the user back to the screen they viewed most recently. In some situations, you can control where the Back button takes the user:
popUpTo
attribute in the navigation.xml
file.popUpToInclusive
attribute to true
. All destinations up to and including this destination are removed from the back stack.popUpTo
attribute is set to the app's the starting destination and popUpToInclusive
is set to true
, the Back button takes the user all the way out of the app.Screens in an Android app can have an on-screen Up button that appears at the top left of the app bar. (The app bar is sometimes called the action bar.) The Up button navigates "upwards" within the app's screens, based on the hierarchical relationships between screens.
The navigation controller's NavigationUI
library integrates with the app bar to allow the user to tap the Up button on the app bar to get back to the app's home screen from anywhere in the app.
To link the navigation controller to the app bar:
onCreate()
, call setupActionBarWithNavController()
on the NavigationUI
class, passing in the navigation controller:val navController = this.findNavController(R.id.myNavHostFragment)
NavigationUI.setupActionBarWithNavController(this,navController)
onSupportNavigateUp()
method to call navigateUp()
in the navigation controller:override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return navController.navigateUp()
}
}
The options menu is a menu that the user accesses from the app bar by tapping the icon with the three vertical dots . To create an options menu with a menu item that displays a fragment, make sure the fragment has an ID. Then define the options menu and code the
onOptionsItemSelected()
handler for the menu items.
1. Make sure the fragment has an ID:
2. Define the options menu:
options_menu.xml
. The file is stored in the Res > Menu folder.options_menu.xml
file in the design editor and drag a Menu Item widget from the Palette pane to the menu.onClick
behavior for the menu item.3. Code the onClick
handler for the menu item:
onCreateView()
, callsetHasOptionsMenu(true)
to enable the options menu.onCreateOptionsMenu()
to inflate the options menu:override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
inflater?.inflate(R.menu.options_menu, menu)
}
onOptionsItemSelected()
method to take the appropriate action when the menu item is clicked. The following code displays the fragment that has the same ID as the menu item. (This code only works if the menu item and the fragment have identical ID values.)override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return NavigationUI.onNavDestinationSelected(item!!,
view!!.findNavController())
|| super.onOptionsItemSelected(item)
}
The navigation drawer is a panel that slides out from the edge of the screen. There are two ways for the user to open the navigation drawer:
To add a navigation drawer to your app:
build.gradle (app)
.These steps are explained in more detail below.
1. Add dependencies to build.gradle
:
build.gradle (app)
file:dependencies {
...
implementation "com.google.android.material:material:$supportlibVersion"
...
}
2. Give each destination fragment an ID:
3. Create the menu for the drawer:
navdrawer_menu
) for a navigation drawer menu. This creates a new navdrawer_menu.xml
file in the Res > Menu
folder.4. Add the drawer to the layout for the fragment:
<androidx.drawerlayout.widget.DrawerLayout>
as the root view.<com.google.android.material.navigation.NavigationView>
view to the layout.5. Connect the drawer to the navigation controller:
onCreate()
, use NavigationUI.setupWithNavController()
to connect the navigation drawer with the navigation controller:val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
this, R.layout.activity_main)
NavigationUI.setupWithNavController(binding.navView, navController)
6. Set up the drawer button in the app bar:
onCreate()
in the activity that creates the navigation controller (which is typically the main activity), pass the drawer layout as the third parameter to NavigationUI.setupActionBarWithNavController
:val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
this, R.layout.activity_main)
NavigationUI.setupActionBarWithNavController(
this, navController, binding.drawerLayout)
onSupportNavigateUp()
to return NavigationUI.navigateUp()
. Pass the navigation controller and the drawer layout to navigateUp()
.override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return NavigationUI.navigateUp(navController, drawerLayout)
}
Udacity course:
Android developer documentation:
NavigationUI
NavHostFragment
Material Design documentation:
This section lists possible homework assignments for students who are working through this codelab as part of a course led by an instructor. It's up to the instructor to do the following:
Instructors can use these suggestions as little or as much as they want, and should feel free to assign any other homework they feel is appropriate.
If you're working through this codelab on your own, feel free to use these homework assignments to test your knowledge.
Add a Rules button and an About button to the layout for the TitleFragment
as shown below. When the user taps the Rules or About button, the app navigates to the RulesFragment
or AboutFragment
, as appropriate.
On each of the layouts for the RulesFragment
and the AboutFragment
, add a Play button that navigates to the GameFragment
as shown here:
Hint: You need to update the layouts for these two fragments to enable data binding.
Change the back stack to enable the following user flow:
RulesFragment
screen or the AboutFragment
screen to the GameFragment
.TitleFragment
, not to the RulesFragment
or AboutFragment
. In other words, when the user taps the Play button while viewing the rules or the information about the game, then taps the Back button, the RulesFragment
or the AboutFragment
is removed from the back stack.
How do you enable your project to use navigation components?
Activity
class extends the class NavigationActivity
.NavigationController
class as the launch activity.<uses-navigation>
to the Android manifest file.navigation-fragment-ktx
and navigation-ui-ktx
in the build.gradle (module)
file.Where are the possible routes through your app defined?
navigation.xml)
in the res > layout folder.navigation.xml)
in the app > navigation folder.navigation.xml)
in the res > navigation folder.android-manifest.xml
file in the <navigation>
element.Which of the following statements about the NavHostFragment
are true? Select all that apply.
NavHostFragment
swaps the fragments in and out as necessary.NavHostFragment
in the Project view to open the navigation graph.NavHostFragment
to the main layout by adding a <fragment>
whose name is androidx.navigation.fragment.NavHostFragment
. NavHostFragment
subclass and implement the onNavigate()
method to handle different kinds of navigation (such as button clicks).Which of the following statements about the navigation graph are true? Select all that apply.
type
of a connection between fragments is Action
.type="navigation"
attribute to every <fragment>
that is included in the navigation graph.navigation.xml
) in the Android Studio Project pane, then click the Design tab.Where do you set the ID of a fragment be used in navigation?
ID
attribute in the design editor or in the layout XML file in the res > layout folder.ID
attribute in the navigation graph or in the navigation XML file in the res > navigation folder.ID
variable in the relevant Fragment
class.The News app has a NewsFragment
that displays a Show headlines button. The goal is that when the user clicks this button, the app navigates to the HeadlinesFragment
.
Assume that you've added a connection from the NewsFragment
to the HeadlinesFragment
in the navigation graph, as shown here:
What else do you need to do so that when the user taps the Show headlines button, the app navigates to the ShowHeadlinesFragment
?
onclickListener
for the Show headlines button, call navigate()
on the navigation controller, passing the class name of the destination fragment (in this case HeadlinesFragment
) .onclickListener
for the Show headlines button, call navigate()
on the navigation controller, passing the action that connects the NewsFragment
to the HeadlinesFragment
.onclickListener
for the Show headlines button, call navigateTo()
on the container fragment, passing the class name of the destination fragment (in this case HeadlinesFragment
) .When users navigate through an app, sometimes they want to retrace their steps back through the screens they have already visited.
Assume the following:
fragmentA
is connected to fragmentB
by action_FragmentA_to_FragmentB
. fragmentB
is connected to fragmentC
by action_FragmentB_to_FragmentC
Which of the following statements are true regarding navigating forward and backward through the app? (Choose all that apply.)
action_FragmentA_to_FragmentB
action specifies that when the user is at FragmentA
, the next destination in the app is FragmentB
.action_FragmentA_to_FragmentB
action sets the next destination that the user goes to, whether the user taps a button in the app or taps the Back button at the bottom of the screen.popUpTo
attribute of the action can modify where the app navigates to if the user taps the system Back button.popUpTo
attribute of the action can modify where the user goes next as they navigate forward through the app.When users navigate through an app, sometimes they want to retrace their steps back through the screens they have already visited. However, you can use the popUpTo
and popUpToInclusive
attributes of an action to modify the path backward through the app.
Assume the following:
fragmentA
is connected to fragmentB
by action_FragmentA_to_FragmentB
. fragmentB
is connected to fragmentC
by action_FragmentB_to_FragmentC
.The user navigates from fragmentA
to fragmentB
to fragmentC
, then taps the system Back button. In this situation, let's say you want the app to navigate back to fragment
A
(instead of fragmentB
). What's the correct way to set the popUpTo
and popUpToInclusive
attributes?
action_FragmentA_to_FragmentB
, set popUpTo
to fragmentB
and popUpToInclusive
to no value.action_FragmentB_to_FragmentC
, set popUpTo
to fragmentA
and popUpToInclusive
to true
.action_FragmentA_to_FragmentB
, set popUpTo
to fragmentA
and popUpToInclusive
to true
.action_FragmentB_to_FragmentC
, set popUpTo
to fragmentA
and popUpToInclusive
to true
.action_FragmentA_to_FragmentB
, set popUpTo
to none and popUpToInclusive
to no value. (You can omit both attributes.)action_FragmentB_to_FragmentC
, set popUpTo
to fragmentA
and popUpToInclusive
to true
.action_FragmentA_to_FragmentB
, set popUpTo
to none and popUpToInclusive
to no value. (You can omit both attributes.)action_FragmentB_to_FragmentC
, set popUpTo
to fragmentA
and popUpToInclusive
to false.
Assume that the action action_headlinesFragment_to_newsArticle
in the destination graph has a popUpTo
value of newsFragment
:
Assume that the user opens the app and navigates through the screens in the following sequence (without using the Back button):
Open app into News home > Headlines > News details
When the user is viewing the News detail screen, what happens If they tap the system Back button at the bottom of the screen?
Select all that apply (remembering that popUpTo
is newsFragment
).
popUpToInclusive
is true
:popUpToInclusive
is false
:popUpToInclusive
is true
:popUpToInclusive
is false
:Where do you define the items for a menu?
<item>
tag for each menu item in the menu
.xml
file in res > drawer folder. For the options menu, add an <item>
tag for each menu item in the menu
.xml
file in res > options folder.<menu>
tag that contains <item>
tags for each item.menu_name
.xml
file in the res > menu folder, add an <item>
tag for each menu item. Create separate XML files for each separate menu.android_manifest.xml
file, add a <menus>
tag that contains a <menu>
tag for each menu. For each <menu>
tag, add an <item>
tag for each menu item.To enable the options menu in your app, you need to define the menu items. Then what do you need to do in the Activity
or Fragment
where the options menu is to appear?
Select all that apply:
setHasOptionsMenu(true)
in onCreate()
for an activity, or in onCreateView()
for a fragment. onCreateOptionsMenu()
in the activity or fragment to create the menu.onClick
attribute in the menu's XML file to onShowOptionsMenu
, unless you are implementing a custom onClick
listener for the options menu, in which case specify the name of the custom onClick
listener instead.onOptionsItemSelected()
in the activity or fragment to determine what happens when a user selects a menu item in the options menu.What do you need to do to enable a navigation drawer in your app? You can assume that your project is using the navigation graph and that you've already defined the menu items.
Select all that apply:
<DrawerLayout>
as the root view in the relevant layout file, and add a <NavigationView>
tag to that layout. <Navigation>
as the root view in the relevant layout file, and add a <NavigationView>
tag to that layout. <NavigationView>
in the layout, set the android:menu
attribute to the navigation drawer menu.Following on from the previous question, you need to write some code to enable the navigation drawer to be displayed when the user swipes in from the left side of the screen?
In onCreate()
within the Activity
that creates the navigation controller, what is the right code to add?
NavigationUI.setupWithNavController(
navigationLayoutID, navigationMenuID)
NavigationUI.setupWithNavController(
navigationView, navigationController)
NavigationDrawer.setupWithNavInterface(
navigationView, navigationController)
NavigationDrawer.setupWithNavController(
navigationView, navigationMenuID)
How do you add support for the Up button at the top of the screen to enable users to get back to the app's home screen from anywhere in the app? What do you need to do in the relevant Activity
?
Select all that apply:
res > menu
folder, create the up_menu.xml
file.NavigationUI.setupActionBarWithNavController(context,navigationController)
onSupportNavigateUp()
method to call navigateUp()
on the navigation controller.ID
of HomeFragment
.Check that the app has the following features:
TitleFragment
screen has a Rules and About button as shown below.RulesFragment
or AboutFragment
, as appropriate.The RulesFragment
and AboutFragment
screens both have a Play button that navigates to the GameFragment
as shown here:
Check that the layouts for these two fragments both have data binding enabled.
Check the following user flow:
The app should navigate back to the title fragment, not to the rules fragment or the about fragment.
Start the next lesson:
For links to other codelabs in this course, see the Android Kotlin Fundamentals codelabs landing page.