今天小編要分享的還是Android Jetpack庫的基本使用方法,本篇介紹的內容是Jetpack Navigation組件,讓我們一起學習,為完成年初制定的計劃而努力吧! 組件介紹 導航,是指提供用戶在應用程式中的不同內容之間進行瀏覽、退出的交互功能。如我們在Android手機上常常用到的物理/虛 ...
今天小編要分享的還是Android Jetpack庫的基本使用方法,本篇介紹的內容是Jetpack Navigation組件,讓我們一起學習,為完成年初制定的計劃而努力吧!
組件介紹
導航,是指提供用戶在應用程式中的不同內容之間進行瀏覽、退出的交互功能。如我們在Android手機上常常用到的物理/虛擬返回按鍵、桌面(Home)鍵、歷史記錄(Recent)鍵、ActionBar 返回鍵等等。
Jetpack庫中的Navigation組件由以下三個關鍵部分組成:
導航圖:一種XML資源,包含所有與導航有關的信息,如Fragment配置、跳轉行為/方向、動畫等等;
NavHost:一個空容器,用於顯示導航圖中的目的地,項目中需要包含一個實現NavHost介面的預設NavHostFragment容器;
NavController:在NavHost容器內管理應用程式的導航行為。當用戶在應用程式中切換界面時,NavController協調容器中的目標內容交換。
優點
使用導航組件有很多好處:
能夠處理Fragment切換
能夠正確處理向上、返回的預設行為
提供動畫和過渡的標準化資源
提供深層鏈接功能
包含導航UI模式,例如抽屜導航和底部導航,開發者無需進行額外的處理
保護導航之間數據傳遞的類型安全
提供ViewModel支持,多Fragment間可共用ViewModel數據
提供AndroidStudio圖形化查看/編輯導航功能(>= 3.3版本)
簡單使用
下麵是一個使用導航組件進行開發的Demo運行效果:
從實現效果上來看,整個應用程式共有8個界面,分別是主界面、註冊界面、排行界面、用戶匹配、游戲界面、失敗界面、成功界面、用戶界面。
主要涉及的邏輯有:
打開應用進入主界面
主界面提供兩個功能,一個開始註冊;另一個進入排行界面
註冊界面提供開始匹配功能
用戶匹配提供開始游戲功能
游戲界面操作後會進入成功或失敗界面
游戲成功界面可進入排行界面或匹配界面繼續游戲
游戲失敗界面可返回到匹配界面重試
排行界面可進入用戶界面查看信息
好了,整個應用界面之間涉及的主要邏輯都已經理清楚了,開始導入Jetpack導航組件。
環境配置
使用AS 3.3及以上版本
添加依賴項支持
implementation deps.navigation.fragment_ktx
implementation deps.navigation.runtime_ktx
//implementation "androidx.navigation:navigation-fragment-ktx:2.1.0"
//implementation "androidx.navigation:navigation-ui-ktx:2.1.0"
導航圖
導航圖的創建是整個應用的核心所在,它描述了所有行為的觸發順序。通過AS Design功能可看到整個應用的界面並且覆蓋所有界面可能執
行的順序。
navigation demo導航圖
使用AndroidStudio創建導航圖時,選擇Resource type為navigation,預設會創建res/navigation目錄,並將資源文件放置於此目錄下。
以title_screen主界面配置為例,來看一下xml的構成:
<navigation ...
//指定了啟動當前導航時顯示的界面
app:startDestination="@+id/title_screen">
<fragment
android:id="@+id/title_screen"
android:name="com.example.android.navigationsample.TitleScreen"
android:label="fragment_title_screen"
tools:layout="@layout/fragment_title_screen">
//每一個action都代表了界面上提供跳轉到其他界面的行為
<action
android:id="@+id/action_title_screen_to_register"
app:destination="@id/register"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
//設置了動畫和過渡效果
<action
android:id="@+id/action_title_screen_to_leaderboard"
app:destination="@id/leaderboard"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
</fragment>
.../>
在導航圖配置時,有四個需要註意的屬性:
popUpTo
popUpToInclusive
launchSingleTop
deepLink
//launchSingleTop代表啟動當前fragment後,會棧頂復用
<action
android:id="@+id/action_register_to_match"
app:destination="@id/match"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:launchSingleTop="true"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
//deepLink及深度鏈接,應用可通過Uri方式啟動當前Fragment:
//holder.item.findNavController().navigate(Uri.parse("https://www.example.com/user/Flo"))
//此種方法為靜態配置,動態配置方法請參考官方說明文檔
<fragment
android:id="@+id/user_profile"
android:name="com.example.android.navigationsample.UserProfile"
android:label="fragment_user_profile"
tools:layout="@layout/fragment_user_profile">
<argument android:name="userName"
android:defaultValue="name"/>
<deepLink app:uri="www.example.com/user/{userName}" />
</fragment>
<action
android:id="@+id/action_in_game_to_resultsWinner"
app:destination="@id/results_winner"
app:popUpTo="@+id/match"
app:popUpToInclusive="false"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"/>
//popUpTo屬性表示堆棧返回到某個界面,其後的棧數據清空
//popUpToInclusive屬性為true表示回到指定界面時,界面棧中是否還包括當前界面
//(如果棧中已經包含了指定要跳轉的界面,那麼只會保留一個,不指定則棧中會出現兩個
//界面相同的Fragment數據)
AndroidManifest與佈局文件配置
如果要使用導航組件的深度鏈接功能,則需要在AndroidManifest中聲明導航圖,以便深度鏈接功能正常使用。
<activity...
<nav-graph android:value="@navigation/navigation" />
...
</activity>
導航功能的使用需要在NavHostFragment容器中實現,因此需要指定佈局顯示時使用的容器,設置預設NavHost,設置導航圖。
<layout>...
<fragment
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navigation"/>
.../>
代碼實現
整個Demo使用單Activity,多Fragment架構,MainActivity啟動時,載入NavHostFragment容器,解析navigation容器圖,通過startDestination屬性找到首界面進行顯示(本例首界面為TitleScreen)。
如下為TitleScreen的代碼實現:
class TitleScreen : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_title_screen, container, false)
view.findViewById<Button>(R.id.play_btn).setOnClickListener {
Navigation.findNavController(view).navigate(R.id.action_title_screen_to_register)
}...
return view
}
}
到此,使用導航組件進行應用程式開發的基本流程已經結束,當然導航組件提供的功能遠不止如此,它還有如頁面間數據類型的安全保護,手勢導航,導航嵌套、條件導航,自定義動畫過渡效果,使用NavigationUI更新界面等高級使用方法。具體使用可參考Google官方文檔說明。
- END -