导航抽屉解锁模式被忽略

Navigation drawer unlock mode ignored

所以我有一个带有 activity (MainActivity) 的应用程序,并且我正在使用导航架构组件。所以它有 DrawerLayout 包装 fragment 视图。

这是Activity class中的两个方法,负责drawerLayout.

的锁定和解锁
...

fun lockNavDrawer() {
    drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}

fun unLockNavDrawer() {
    drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
}

...

有一些 fragments 需要导航抽屉。一切正常,除了那些不应该有 Drawer.

的片段

所以,在我的基本片段中,我正在实现一个接口 (HasToolbar),它有一个名为 hasNavigationDrawer 的变量,在基本片段的 onDestroyView 中,我正在做这个。抽屉上锁没问题

if (this is HasToolbar) {
    if (hasNavigationDrawer) {
       activity.lockNavDrawer()
    }
    unregisterListeners()
}

但是当我在基础片段onViewCreated中这样做时

if (this is HasToolbar) {
    if (hasNavigationDrawer) {
       activity.unlockNavDrawer()
    }
}

它不会解锁抽屉,因此不会打开应该有抽屉的片段内的抽屉。

如果我在 fragment 中执行此操作,它会保持解锁状态。

lockNavDrawer()
unLockNavDrawer()

如果您查看回调的顺序,您会发现新 Fragment 的 onViewCreated() 在 之前 被调用 onDestroyView()旧片段。这在动画方面特别有意义,因为要在两个 Fragment 之间平滑地动画,新 View 和旧 View 必须共存,并且只有在动画结束后旧 Fragment 才会被销毁。片段,为了保持一致,无论你有没有动画,都使用相同的顺序。

理想情况下,您的片段根本不应该达到 Activity 以影响 Activity 的行为。根据 Listen for Navigation Events documentation,您应该改为使用 OnDestinationChangedListener 来更新 Activity 的 UI。然而,侦听器仅接收有关目的地及其参数的信息,因此要使用这种方法,您需要向导航图中添加一个参数:

<!-- this destination leaves the drawer in its default unlocked state -->
<fragment
  android:id="@+id/fragment_with_drawer"
  android:name=".MainFragment" />
<!-- the drawer is locked when you're at this destination -->
<fragment
  android:id="@+id/fragment_with_locked_drawer"
  android:name=".SettingsFragment">
  <argument
    android:name="lock_drawer"
    android:defaultValue="true"/>
</fragment>

那么你的OnDestinationChangedListener可能看起来像

navController.addOnDestinationChangedListener { _, _, arguments ->
  if(arguments?.getBoolean("lock_drawer", false) == true) {
    lockNavDrawer()
  } else {
    unlockNavDrawer()
  }
}