本頁說明在應用程式中與導航地圖互動的最佳做法。
盡可能使用 NavigationFragment,而非 NavigationView
NavigationFragment 會包裝 NavigationView,並自動處理生命週期回呼,因此您不必自行管理。這種做法較不容易出錯,建議您在應用程式中使用這種導覽方式。使用 NavigationFragment 時,請勿直接叫用 NavigationView 生命週期事件。
如果使用 NavigationView,請在叫用生命週期方法時嚴格遵守順序
NavigationView 會代管 Navigation 地圖,並密切追蹤 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" />
變更後 (8.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() 查詢片段:
變更前 (7.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 } }
變更後 (8.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())。