Jetpack Navigation 页面管理

项目中在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
NavHostFragment
继续看
Jetpack Navigation 页面管理_第1张图片

发现:
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,升级。

完成后,果然:
Jetpack Navigation 页面管理_第2张图片

你可能感兴趣的:(Android,Jetpack)