导航抽屉解锁模式被忽略
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()
}
}
所以我有一个带有 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()
}
}