項目中在Drawerlayout的抽屜中放入fragment作爲Navigation的容器
用戶按下返回鍵需要判斷:
當前是S頁
或者是一級頁面=》收起抽屜;
不是S
頁並且它不是二級頁面=》返回上一頁。
也就是說S頁
不是所有頁面的起始頁。
開始的時候只有幾個頁面,於是手動根據ID來控制。
舉個例子
Navigation圖如下:
A
B->C
Navigation必須要有startDestination節點,隨便設一個A
。
當頁面是A,返回鍵直接收起抽屜
當頁面是B,返回鍵直接收起抽屜
當頁面是C,返回鍵返回B
治標不治本
原始的手動控制
when (nav.currentDestination) {
nav.graph.findNode(R.id.changeNameFragment), nav.graph.findNode(R.id.discountCodeFragment), nav.graph.findNode(R.id.orderFragment) -> super.onBackPressed()
nav.graph.findNode(R.id.shareFragment) -> {
if (currentPage == 0) closeEndDrawer()
else super.onBackPressed()
}
else -> closeEndDrawer()
}
差不多就這意思,當頁面多了之後就開始煩了,比如上面的shareFragment
,可能多個地方出現,這個地方它可能是二級頁面,那個地方它可能是一級頁面,不得不去解決這個問題。
徹底解決
Navigation
其實就是一個棧控制的,supportFragmentManager.fragments
中可以看見一個NavHostFragment
繼續看
發現:
mBackStack[0]
對應我們裝Navigation的那個fragment
<fragment
android:id="@+id/nav_drawer_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_drawer_main" />
mBackStack[1]
對應我們app:navGraph
中的startDestination
mBackStack[2]
對應我們當前顯示的fragment
再一次測試發現,即使調用
nav.popBackStack(R.id.xxx,true)
或者
nav.Graph(R.navigation.xxx)
來清除所有導航頁面,然後直接跳轉到我們需要的頁面,這個startDestination
還是會存在。
所以現在返回鍵的判斷邏輯就可以這麼寫。
if(抽屜是展開的){
// 當前是起始頁 || 上一頁就是起始頁
if(nav.currentDestination == startDestination頁面對應的ID || mBackStack.size == 3){
closeDrawer()//收起抽屜
}else{
// Navigation默認處理返回鍵
super.onBackPressed()
}
}else{
其他操作
}
但是這個mBackStack是私有的獲取不到,想了想會不會谷歌當時沒考慮周全,也許後續升級會開放這個屬性。
檢查當前Navigation版本:2.2.2,最新版本:2.3.0,升級。
完成後,果然: