问题
So I have this app with one activity (MainActivity
) and I'm using the navigation architecture component. So it has DrawerLayout
which is wrapping the fragment
view.
These are two methods in the Activity class which are responsible for Locking and Unlocking of the drawerLayout
.
...
fun lockNavDrawer() {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}
fun unLockNavDrawer() {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
}
...
There are some fragments
which need to have the navigation drawer. Everything is working fine except those fragments which not suppose to have the Drawer
.
So, in my base fragment, and I'm implementing an interface (HasToolbar
) which have a variable called hasNavigationDrawer
and in the onDestroyView
of the base fragment, I'm doing this. The locking of the Drawer is fine.
if (this is HasToolbar) {
if (hasNavigationDrawer) {
activity.lockNavDrawer()
}
unregisterListeners()
}
But when I do this in the onViewCreated
of the base fragment
if (this is HasToolbar) {
if (hasNavigationDrawer) {
activity.unlockNavDrawer()
}
}
It does not unlock the drawer hence it does not open the drawer inside the fragment which suppose to have the drawer.
If I do this inside a fragment
it works it stays unlocked.
lockNavDrawer()
unLockNavDrawer()
回答1:
If you look at the ordering of the callbacks, you'll see that the onViewCreated()
of the new Fragment is called before the onDestroyView()
of the old Fragment. This makes particular sense when it comes to animations since to smoothly animate between two Fragments, both the new View and the old View must coexist and only after the animation ends does the old Fragment get destroyed. Fragments, in order to be consistent, use the same ordering whether you have an animation or not.
Ideally, your Fragments shouldn't be reaching up to the Activity at all to affect the Activity's behavior. As per the Listen for Navigation Events documentation, you should instead use an OnDestinationChangedListener
to update your Activity's UI. The listener only receives information about the destination and its arguments however, so to use this approach you'd want to add an argument to your navigation graph:
<!-- 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>
Then your OnDestinationChangedListener
could look like
navController.addOnDestinationChangedListener { _, _, arguments ->
if(arguments?.getBoolean("lock_drawer", false) == true) {
lockNavDrawer()
} else {
unlockNavDrawer()
}
}
来源:https://stackoverflow.com/questions/57925413/navigation-drawer-unlock-mode-ignored