-
Notifications
You must be signed in to change notification settings - Fork 0
Lab 6
We will build out the navigation infrastructure for our application using the Navigation component from Android Jetpack. By the end of this lab, you should have:
- a navigation graph the describes the navigation flow of your application
- a bottom navigation view that includes 2 tabs for "my notes" and "study guide"
- buttons that allow you to view "create note" and "note details" from the "my notes" screen
-
Create a new Navigation resource file named
main_navigation.xml
- Right-click on the
res
directory - Select
New
->Android Resource File
- Select
navigation
as the resource type
- Right-click on the
-
Add
MyNotesFragment
andStudyGuideFragment
as destinations in the navigation graph- This can be done using the "design editor" or directly in the xml
- To add from the designer, click the button with the green
+
, and select the desiredFragment
-
In
activity_main.xml
, replace the existingFragment
containerFrameLayout
with aFragmentContainerView
- Add the following attribute
android:name="androidx.navigation.fragment.NavHostFragment"
- Remove the elevation attribute
- Add the following attribute
-
Connect the nav graph to our
FragmentContainerView
- Add
app:navGraph="@navigation/main_navigation"
to theFragmentContainerView
inactivity_main.xml
- Add
-
Remove the manual
FragmentTransaction
code fromMainActivity
- We will be replacing these later in the Lab
- Your click handlers can just be left empty for now
-
Within
MainActivity
get a reference to theNavController
from theNavHostFragment
- Use
binding.fragmentContainer.getFragment<NavHostFragment>().navController
- Store this reference in a variable named
navController
- Use
-
Create a menu resource named
navigation_items.xml
- Right-click on the
res
directory and selectNew
->Android Resource File
- Select
menu
as the resource type - Add 2 menu items whose ids match the ids of the navigation destinations within
main_navigation.xml
- Give each menu item a human-readable label
- Right-click on the
-
Add a
BottomNavigationView
toactivity_main.xml
- remove existing buttons and any code referencing them
- add the
BottomNavigationView
toactivity_main.xml
and constrain it to bottom of parent - adjust the fragment container to be constrained to the top of the bottom navigation view
- define the items in our bottom nav view by setting the menu attribute to our
navigation_items.xml
menu -app:menu="@menu/navigation_items"
-
Connect our
BottomNavigationView
to ourNavController
- Within
MainActivity
, callBottomNavigationView.setupWithNavController(navController)
to connect yourBottomNavigationView
with theNavController
- Your
BottomNavigationView
should now change fragments when you select a tab
- Within
-
Add
NoteDetailFragment
andCreateNoteFragment
as destinations withinmain_navigation.xml
-
Add
Action
s connectingMyNotesFragment
to bothNoteDetailFragment
andCreateNoteFragment
-
Can add an
Action
by dragging from one destination in the designer to another -
Can add an
Action
by editing the xml directly -
Add a "show details" Button and a "create note" button to
MyNotesFragment
-
Update click handlers in
MyNoteFragment
to navigate to the desired fragments using the generatedAction
ids associated with theActions
defined inmain_navigation.xml
-
ex:
findNavController().navigate(R.id.action_myNotesFragment_to_createNoteFragment)
-
Your app should now navigate to all the fragments as before
-
Notice however that clicking the Back button closes the app instead of popping the last
Fragment
-
Connect
Toolbar
toNavController
-
Change app theme to implement
DayNight.NoActionBar
-
Add
androidx.appcompat.widget.Toolbar
to the top of youractivity_main.xml
layout -
Update the constraints for your
FragmentContainerView
so it sits below theToolbar
and above theBottomNavigationView
-
From
MainActivity
callsetSupprtActionBar()
and pass in a reference to yourToolbar
-
Create an instance of
AppBarConfiguration
and pass insetOf(id.myNotesFragment, id.studyGuideFragment)
-
Call
Toolbar.setupWithNavController()
and pass in the reference to theNavController
andAppBarConfiguration
. This will prevent the back icon showing in theToolbar
when we visit either of our bottom navigation destinations. -
In
MainActivity
, overrideonBackPressed()
to first check ifNavController.popBackStack()
returnstrue
before callingsuper.onBackPressed()
-
This should prevent the app from closing if we have navigated to a
Fragment
destination -
Our navigation is still not ideal however. Our
Toolbar
andBottomNavigationView
still don't behave as we want. -
For each destination in
main_navigation.xml
add a"ShowBottomNav"
argument and specify a boolean value to control whether theBottomNavigationView
should be visible when that destination is showing -
Add a
OnDestinationChangedListener
to yourNavController
-
Within the
OnDestinationChangedListner
, show, or hide, theBottomNavigationView
based on the"ShowBottomNav"
argument passed to the callback -
For both navigation
Action
s inmain_navigation.xml
, add an enter animation usingapp:enterAnim="@android:anim/slide_in_left"
- Give user-friendly names to each navigation destination to improve the look of the
Toolbar
title.- Check the
label
attribute of each destination inmain_navigation.xml
- Check the
- Give icons to the
BottomNavigationView
menu items
Create a custom animation resource to further customize your Navigation animations.
- Look at
@android:anim/slide_out_down
for inspiration. - Review the
Animation
properties of any selected navigationAction
to see which types ofFragment
transitions can be animated for anAction
- Getting Started with Navigation Component
- Navigating between destinations
- Updating Bottom Navigation with Navigation Component
- Animating Between Destinations
- Material Design: Bottom Navigation
- Material Design: Top App Bar
While the documentation lists quite a few related dependencies, for this Lab you should only need these two dependencies for the Navigation Component
dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:2.5.0"
implementation "androidx.navigation:navigation-ui-ktx:2.5.0"
}
A Navigation graph can edited in 2 ways
- Using the interactive UI designer
- From XML
Anything you change in the UI designer will be reflected in the XML. Review this guide for a detailed summary of the different methods of adding/updating destinations in a nav graph.
You can do this 2 ways
- Open the UI designer, and click the
Add Destination
button in the toolbar. Look for the green + icon. - In the XML, add a
<Fragment>
tag and specify theandroid:id
andandroid:name
attributes
This can be done 2 ways
- In the UI designer, drag from one Destination to the other. This should create a line connecting the two Destinations. This line represents the Action and can be selected/configured.
- In the XML, find the
<Fragment>
tag for the destination you're starting from. Within that tag, add a<action>
specifying theandroid:id
andapp:destination
attributes
Do you need to check whether a Navigation destination includes a specific argument when navigated to?
Let's imagine we're checking the value of "ShowAppBar"
. Within our OnDestinationChangedListener
we could check for the argument value like this:
val showAppBar = arguments?.getBoolean("ShowAppBar", false) == true