Page Summary
-
Prioritize using
SupportNavigationFragmentoverNavigationViewfor simplified lifecycle management and error reduction. -
When using
NavigationViewdirectly, ensure strict adherence to the Android lifecycle order when invoking its lifecycle methods to prevent issues like memory leaks and UI errors. -
Invoke
NavigationViewlifecycle events exclusively from either the activity or the fragment to maintain order and avoid duplicate calls.
This page explains best practices for interacting with the Navigation map in your app.
Use NavigationFragment instead of NavigationView, whenever possible
NavigationFragment wraps NavigationView and automatically handles its
lifecycle callbacks, so you don't need to manage them yourself. This approach
is less error-prone and is the recommended way to use navigation in your app.
When using NavigationFragment, don't invoke NavigationView lifecycle events
directly.
If using NavigationView, use strict ordering when invoking lifecycle methods
NavigationView hosts the Navigation map and closely follows the lifecycle
events as Android activities and fragments, taking specific actions when these
lifecycle events are invoked. NavigationView executes multiple initializations
on NavigationView#onCreate and NavigationView#onStart, and cleanups on
NavigationView#onStop and NavigationView#onDestroy, as well as when other
lifecycle events are processed.
NavigationView lifecycle methods have the same meaning as they do for Android
activities or fragments. For example, onCreate of NavigationView roughly
translates to and should be invoked by lifecycle callbacks from the Android
activity or fragment. Because the NavigationView lifecycle callbacks are
based on and invoked in the same order as the Android lifecycle callbacks,
strict ordering of these NavigationView methods is required. Otherwise, you
might experience memory
leaks, UI
errors, location not being updated, and other issues.
For more information about the Android activity lifecycle, see the Activity-lifecycle concepts section in the Android developer documentation.
The following table shows when other lifecycle methods should be invoked, after specified lifecycle methods:
| Lifecycle method | Invoked where in the activity lifecycle | Invoked after which lifecycle method |
|---|---|---|
onConfigurationChanged()
|
Invoked when the UI is in the foreground and the configuration changes. | Always after onStart()
|
onTrimMemory()
|
Invoked when an activity is in the background. | Always after onPause()
|
onSaveInstance()
|
Invoked before an activity is destroyed. | Always after onStop()
|
Don't call these lifecycle methods multiple times without calling the
corresponding closing method first. In addition, keep in mind that if some of
these Android lifecycle callbacks are managed by the app itself, and the
NavigationView is added to the fragment after creation or start, the app
should call the specific methods in proper order to correctly initialize the
Navigation SDK.
For additional guidance on using these methods, see the Navigation SDK demo app.
If using NavigationView, invoke lifecycle events from the activity or fragment, not both
To keep the strict ordering of the lifecycle methods, invoke these events from either the activity or fragment lifecycle callbacks, which receive these events in order. This approach ensures that apps don't need to coordinate between fragments and activities and cause duplicate calls.
Update from SupportNavigationFragment to NavigationFragment
Starting in Navigation SDK v8.0.0, NavigationFragment replaces the
deprecated SupportNavigationFragment as the standard fragment container for
turn-by-turn navigation and map display.
NavigationFragment maintains full API parity with SupportNavigationFragment.
To update your app, replace SupportNavigationFragment with
NavigationFragment in your XML layout files and source code imports. All
method signatures and getSupportFragmentManager() calls remain identical.
Update the layout XML
Replace SupportNavigationFragment with NavigationFragment in your layout
XML files:
Before (v7.x and earlier):
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/navigation_fragment"
android:name="com.google.android.libraries.navigation.SupportNavigationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
After (v8.0.0+):
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/navigation_fragment"
android:name="com.google.android.libraries.navigation.NavigationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
If your app uses FragmentContainerView (recommended for hosting fragments),
update the android:name attribute:
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/navigation_fragment"
android:name="com.google.android.libraries.navigation.NavigationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Update the application code
Replace imports and class casts in your Java or Kotlin code. Because both
classes extend androidx.fragment.app.Fragment, continue using
getSupportFragmentManager() to look up the fragment:
Before (v7.x and earlier):
Java
import com.google.android.libraries.navigation.SupportNavigationFragment; public class MainActivity extends AppCompatActivity { private SupportNavigationFragment mNavFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mNavFragment = (SupportNavigationFragment) getSupportFragmentManager() .findFragmentById(R.id.navigation_fragment); } }
Kotlin
import com.google.android.libraries.navigation.SupportNavigationFragment class MainActivity : AppCompatActivity() { private lateinit var navFragment: SupportNavigationFragment override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) navFragment = supportFragmentManager .findFragmentById(R.id.navigation_fragment) as SupportNavigationFragment } }
After (v8.0.0+):
Java
import com.google.android.libraries.navigation.NavigationFragment; public class MainActivity extends AppCompatActivity { private NavigationFragment mNavFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mNavFragment = (NavigationFragment) getSupportFragmentManager() .findFragmentById(R.id.navigation_fragment); } }
Kotlin
import com.google.android.libraries.navigation.NavigationFragment class MainActivity : AppCompatActivity() { private lateinit var navFragment: NavigationFragment override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) navFragment = supportFragmentManager .findFragmentById(R.id.navigation_fragment) as NavigationFragment } }
API parity
You don't need to make any other behavior changes or restructure your code.
NavigationFragment supports all public methods, listener interfaces, and
custom UI controls from SupportNavigationFragment with identical method
signatures (including getMapAsync(), getNavigator(), setEtaCardEnabled(),
and setStylingOptions()).