ios navigation的返回按钮长按_Android Jetpack架构组件 — Navigation入坑详解 [转]
前言
這是最近看見的覺得比較有意思的文,希望對大家的學習有幫助。
Navigation 直接翻譯即為導航,它是 Android Jetpack 組件之一,讓單 Activity 應用成為首選架構。應用內Fragment頁面的跳轉則由 Navigation 來處理,開發者無需在處理 FragmentTransaction 的復雜性以及相關的轉場動畫。
具體使用
在app的gradle.build中添加依賴:
def nav_version = "2.1.0"implementation "androidx.navigation:navigdef nav_version = "2.1.0" implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version"首先我們定義三個Fragment,分別為Fragment1,Fragment2和Fragment3。實現邏輯為Fragment1點擊跳轉到Fragment2,Fragment2點擊跳轉到Fragment3,Fragment3跳轉到Fragment1同時點擊返回鍵時也返回到Fragment1。
navigation: 導航視圖XML的根結點。里面定義相關fragment的跳轉邏輯。
首先需要在res資源目錄下新建 navigation 文件夾,右鍵新建一個Navigation resource file命名為nav_graph_main.xml。
文件左下腳分為兩個Tab:Design和Text。Design視圖是可視化的,可以直接選擇相關fragment。Text視圖是我們手寫相關配置。
我們看下定義的nav_graph_main.xml文件:
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"app:startDestination="@id/fragment1"><fragmentandroid:id="@+id/fragment1"android:name="com.jetpack.jetpackdemo.navigation.fragment.Fragment1"android:label="Fragment1"tools:layout="@layout/fragment1_layout"><actionandroid:id="@+id/fragment1_action"app:destination="@+id/fragment2" /></fragment><fragmentandroid:id="@+id/fragment2"android:name="com.jetpack.jetpackdemo.navigation.fragment.Fragment2"android:label="Fragment2"tools:layout="@layout/fragment2_layout"><actionandroid:id="@+id/fragment2_action"app:destination="@+id/fragment3" /></fragment><fragmentandroid:id="@+id/fragment3"android:name="com.jetpack.jetpackdemo.navigation.fragment.Fragment3"android:label="Fragment3"tools:layout="@layout/fragment3_layout"><actionandroid:id="@+id/fragment3_action"app:popUpTo="@id/fragment1" /></fragment> </navigation>navigation根節點中有個startDestination字段,他表示的是默認展示的是哪一個頁面。通過fragment標簽來定義要路由的相關頁面。id為fragment唯一標識。name為包名,必須保證正確。layout為fragment的布局文件,配置后方便在Design視圖中查看。
fragment中配置了子節點 action 。action表示的就是具體要路由的行為。同樣id也是其唯一標識,destination表示的是目的地,即需要路由到具體的某一個頁面。popUpTo表示彈出到某一個頁面。action還有其他的屬性比如配置動畫等,具體請看Demo。
NavHostFragment是導航視圖的展示容器。
<fragmentandroid:id="@+id/nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="0dp"android:layout_height="0dp"app:defaultNavHost="true"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/nav_graph_main" />name為固定寫法,必須指明為
androidx.navigation.fragment.NavHostFragmentdefaultNavHost字段表示是否攔截返回按鍵操作。
若為true,需要的Activity中重寫onSupportNavigateUp方法。
因為默認情況下返回鍵是不會回退fragment頁面的。
override fun onSupportNavigateUp(): Boolean {return findNavController(R.id.nav_host_fragment).navigateUp() }navGraph字段即為我們配置的navigation導航視圖。
NavController
通過findNavController來獲取NavController,通過controller的navigate或者navigateUp進行頁面之間的路由操作。
那么在三個頁面的點擊按鈕的邏輯就是挑戰相應的頁面:
mBtn.setOnClickListener {Navigation.findNavController(it).navigate(R.id.fragment1_action) }通過指定action的id來告訴Navigation跳轉的邏輯。其他頁面也是一樣。
最終效果:
我們來總結下 navigation、NavHostFragment以及NavController之間的關系。
navigation就是規劃了很多的路線,而這些路線需要在NavHostFragment中才能進行展示。展示后這么多的路線該怎么走呢,決定權就在NavController手中了,就像是方向盤一樣,控制著該走哪一個路線。
傳遞參數
在上文中我們講解了navigation相關的知識,其中還有一個子標簽:argument。是用來定義參數的。比如我們在fragment2標簽中添加argument標簽如下:
<argumentandroid:name="name"android:defaultValue="navigation導航"app:argType="string"app:nullable="false" />那么在fragment1跳轉到fragment2的時候就可以攜帶參數了。其中 name 表示參數名稱。defaultValue即為默認值。argType為參數的類型。nullable表示是否可以為空。
fragment之間傳遞參數有兩種方式:
1.傳統的Bundle方式
2.通過谷歌提供的safeArgs
傳統的Bundle方式
通過Bundle來設置和獲取參數。
在fragment1中進行設置:
mBtn.setOnClickListener {//如果要使用 xml中argument的默認值則直接new Bundle() 傳入即可val args = Bundle()args.putString("name","通過bundle傳遞參數")Navigation.findNavController(it).navigate(R.id.fragment1_action, args) }在fragment2中進行獲取參數:
val args = arguments val name = args?.getString("name") mTvName.text = name這樣就可以將參數進行傳遞了。上面這種方式大家有沒有覺得有什么問題呢?
參數名稱 “name” 我們在三處進行的手動填寫。這樣會很容易導致拼寫錯誤以及修改的時候容易漏改。很不友好。所以谷歌給我們提供了一個插件:safeArgs。下面我們來看下具體使用。
safeArgs
首先需要進行配置,在項目的 build.gradle 中添加classpath配置:
dependencies {classpath 'android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0' }再在app的 build.gradle添加 apply plugin。
apply plugin: 'androidx.navigation.safeargs'項目重新構建后會知道為fragment生成后綴為 Directions的文件。并為navigation中有 argument 標簽的fragment自動生成后綴為Args的文件。
通過后綴為 Directions的文件進行參數的設置。后綴為Args的文件進行參數的獲取。
fragment1中進行設置:
mBtn.setOnClickListener {val args = Fragment1Directions.fragment1Action().setName("通過safeArgs進行參數傳遞")Navigation.findNavController(it).navigate(R.id.fragment1_action, args.arguments) }fragment2中進行獲取:
val name = Fragment2Args.fromBundle(arguments!!).name mTvName.text = name這樣就完成了fragment之間參數的傳遞。完全避免了手動設置參數的邏輯。直接通過setter和getter進行參數的操作。
總結
總體來說Navigation的使用并不復雜,它讓我們單Activity架構成為可能,無需關心具體的fragment的跳轉邏輯。
但是同樣也是有問題的,通過源碼分析我們知道在NavHostFragment的onCreateView中是創建了FrameLayout,也就是說其實真正的容器是FrameLayout。在創建FragmentNavigator的時候內部使用的是replace這個API,而不是show和hide。這就會導致fragment每次生命周期都會重新執行。
所以和ViewModel結合使用效果應該更好。
原文鏈接:Android Jetpack架構組件 — Navigation入坑詳解 - Android架構駱駝的文章 - 知乎 https://zhuanlan.zhihu.com/p/133505164
本文本文在開源項目:https://github.com/xieyuliang/Note-Android中已收錄,里面包含我作為一個八年老Android根據自己的工作和學習經驗整理出來的不同方向的自學編程路線、面試題集合/面經、及系列技術文章等,資源持續更新中...總結
以上是生活随笔為你收集整理的ios navigation的返回按钮长按_Android Jetpack架构组件 — Navigation入坑详解 [转]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移动端布局三种视口_移动端适配之视口和m
- 下一篇: mysql查询语句判断日期_mysql语