本頁說明在應用程式中與 Navigation 地圖互動的最佳做法。
盡可能使用 NavigationFragment,而非 NavigationView
NavigationFragment 會包裝 NavigationView 並自動處理其生命週期回呼,因此您不必自行管理。這種方法較不易出錯,是建議在應用程式中使用導覽的方式。使用 NavigationFragment 時,請勿直接叫用 NavigationView 生命週期事件。
如果使用 NavigationView,請在叫用生命週期方法時嚴格遵守順序
NavigationView 會託管導覽地圖,並密切追蹤 Android 活動和片段等生命週期事件,在叫用這些生命週期事件時採取特定動作。NavigationView 會在 NavigationView#onCreate 和 NavigationView#onStart 上執行多項初始化作業,並在 NavigationView#onStop 和 NavigationView#onDestroy 上執行清理作業,以及在處理其他生命週期事件時執行。
NavigationView 生命週期方法的意義與 Android 活動或片段相同。舉例來說,NavigationView 的 onCreate 大致上會轉譯為 Android 活動或片段的生命週期回呼,且應由這些回呼叫用。由於 NavigationView 生命週期回呼是以 Android 生命週期回呼為基礎,並以相同順序叫用,因此必須嚴格遵守這些 NavigationView 方法的順序。否則,您可能會遇到記憶體流失、UI 錯誤、位置未更新和其他問題。
如要進一步瞭解 Android 活動生命週期,請參閱 Android 開發人員說明文件中的「活動生命週期概念」一節。
下表列出在指定生命週期方法之後,應叫用其他生命週期方法的時機:
| 生命週期方法 | 在活動生命週期中叫用的位置 | 在何種生命週期方法後叫用 |
|---|---|---|
onConfigurationChanged()
|
當 UI 位於前景且設定變更時,系統會叫用這個函式。 | 一律在 onStart() 之後
|
onTrimMemory()
|
當活動在背景執行時叫用。 | 一律在 onPause() 之後
|
onSaveInstance()
|
在活動刪除前叫用。 | 一律在 onStop() 之後
|
請勿多次呼叫這些生命週期方法,除非先呼叫對應的關閉方法。此外,請注意,如果部分 Android 生命週期回呼是由應用程式本身管理,且 NavigationView 是在建立或啟動後新增至片段,應用程式應依適當順序呼叫特定方法,正確初始化 Navigation SDK。
如需使用這些方法的其他指引,請參閱 Navigation SDK 試用版應用程式。
如果使用 NavigationView,請從活動或片段叫用生命週期事件,不要同時從兩者叫用
如要維持生命週期方法的嚴格順序,請從活動或片段生命週期回呼叫用這些事件,這些回呼會依序接收這些事件。這種做法可確保應用程式不必在片段和活動之間協調,並造成重複呼叫。
從 SupportNavigationFragment 更新為 NavigationFragment
自 Navigation SDK 8.0.0 版起,NavigationFragment 取代已淘汰的 SupportNavigationFragment,成為即時路況導航和地圖顯示的標準片段容器。
NavigationFragment 與 SupportNavigationFragment 的 API 完全相同。如要更新應用程式,請在 XML 版面配置檔案和原始碼匯入中,將 SupportNavigationFragment 替換為 NavigationFragment。所有方法簽章和 getSupportFragmentManager() 呼叫都維持不變。
更新版面配置 XML
在版面配置 XML 檔案中,將 SupportNavigationFragment 替換為 NavigationFragment:
舊版 (7.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 (建議用於託管片段),請更新 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() 查詢片段:
舊版 (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 的所有公開方法、事件監聽器介面和自訂 UI 控制項,且方法簽章相同 (包括 getMapAsync()、getNavigator()、setEtaCardEnabled() 和 setStylingOptions())。