本页介绍了在应用中与导航地图互动的最佳实践。
尽可能使用 NavigationFragment 而不是 NavigationView
NavigationFragment 封装了 NavigationView 并自动处理其生命周期回调,因此您无需自行管理这些回调。这种方法不易出错,是建议在应用中使用导航的方式。使用 NavigationFragment 时,请勿直接调用 NavigationView 生命周期事件。
如果使用 NavigationView,请在调用生命周期方法时使用严格的排序
NavigationView 托管导航地图,并像 Android activity 和 fragment 一样密切关注生命周期事件,在这些生命周期事件被调用时采取特定操作。NavigationView 会在 NavigationView#onCreate 和 NavigationView#onStart 上执行多次初始化,在 NavigationView#onStop 和 NavigationView#onDestroy 上执行清理,以及在处理其他生命周期事件时执行初始化和清理。
NavigationView 生命周期方法的含义与 Android activity 或 fragment 的相同。例如,NavigationView 的 onCreate 大致相当于 Android activity 或 fragment 的生命周期回调,并且应由这些回调来调用。由于 NavigationView 生命周期回调基于 Android 生命周期回调,并且以与 Android 生命周期回调相同的顺序调用,因此必须严格按照顺序调用这些 NavigationView 方法。否则,您可能会遇到内存泄漏、界面错误、位置信息未更新等问题。
如需详细了解 Android activity 生命周期,请参阅 Android 开发者文档中的 activity 生命周期概念部分。
下表显示了在指定生命周期方法之后,应何时调用其他生命周期方法:
| 生命周期方法 | 在 activity 生命周期的哪个阶段调用 | 在哪个生命周期方法之后调用 |
|---|---|---|
onConfigurationChanged()
|
当界面位于前台且配置发生更改时调用。 | 始终在 onStart() 之后
|
onTrimMemory()
|
当 activity 处于后台时调用。 | 始终在 onPause() 之后
|
onSaveInstance()
|
在 activity 被销毁之前调用。 | 始终在 onStop() 之后
|
请勿在未先调用相应关闭方法的情况下多次调用这些生命周期方法。此外,请注意,如果这些 Android 生命周期回调中的某些回调由应用本身管理,并且在创建或启动后将 NavigationView 添加到 fragment,则应用应按正确的顺序调用特定方法,以正确初始化 Navigation SDK。
如需有关使用这些方法的更多指导,请参阅 Navigation SDK 演示应用。
如果使用 NavigationView,请从 activity 或 fragment(而非两者)调用生命周期事件
为了保持生命周期方法的严格顺序,请从 activity 或 fragment 生命周期回调中调用这些事件,这些回调会按顺序接收这些事件。这种方法可确保应用无需在 fragment 和 activity 之间进行协调,也不会导致重复调用。
从 SupportNavigationFragment 更新到 NavigationFragment
从 Navigation SDK v8.0.0 开始,NavigationFragment 取代了已弃用的 SupportNavigationFragment,成为精细导航和地图显示的标准 fragment 容器。
NavigationFragment 与 SupportNavigationFragment 保持完全的 API 对等性。
如需更新应用,请在 XML 布局文件和源代码导入中将 SupportNavigationFragment 替换为 NavigationFragment。所有方法签名和 getSupportFragmentManager() 调用都保持不变。
更新布局 XML
将布局 XML 文件中的 SupportNavigationFragment 替换为 NavigationFragment:
之前(v7.x 及更低版本):
<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" />
之后(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" />
如果您的应用使用 FragmentContainerView(建议用于托管 fragment),请更新 android:name 属性:
<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" />
更新应用代码
替换 Java 或 Kotlin 代码中的导入和类转换。由于这两个类都扩展了 androidx.fragment.app.Fragment,因此请继续使用 getSupportFragmentManager() 查找 fragment:
之前(v7.x 及更低版本):
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 } }
之后(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 对等性
您无需进行任何其他行为更改或重构代码。
NavigationFragment 支持 SupportNavigationFragment 中的所有公共方法、监听器接口和自定义界面控件,这些方法具有相同的方法签名(包括 getMapAsync()、getNavigator()、setEtaCardEnabled() 和 setStylingOptions())。