首页 > 解决方案 > 导航抽屉解锁模式被忽略

问题描述

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

这是 Activity 类中的两个方法,负责锁定和解锁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()
    }
}

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

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

lockNavDrawer()
unLockNavDrawer()

标签: androidandroid-fragmentskotlinnavigation-drawer

解决方案


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

理想情况下,您的 Fragments 根本不应该触及 Activity 来影响 Activity 的行为。根据Listen for Navigation Events 文档,您应该改用 anOnDestinationChangedListener来更新 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()
  }
}

推荐阅读