Why does my Navigation Drawer thinks it's closed but remains open after rotation?
-
24-12-2019 - |
Pregunta
I'm currently implementing a Navigation Drawer in my app. Things are working good, but I've run into an issue with the Drawer thinking it's closed after I rotate my device despite it still being visible. Here are a couple of screenshots that illustrate the issue:
Before rotation:
After rotation:
History is the title of the section I was viewing before I opened the Drawer. I preserve the ActionBar title in onSaveInstanceState()
and restore it in onCreate()
, but the function I'm using to set the title is supposed to set the title to the app name when the drawer is open:
private void setTitle(String title)
{
gSectionTitle = title;
TextView actionBarTitle = (TextView) findViewById(R.id.action_bar_title);
if(actionBarTitle != null)
{
// Only set a title if we're looking at History or if the Navigation Drawer is open
Boolean navDrawerOpen = gNavDrawerLayout.isDrawerOpen(gNavDrawerList);
// DEBUG
Log.i(TAG, "navDrawerOpen: " + navDrawerOpen + ", section: " + gSection + ", section title: " + gSectionTitle);
if(navDrawerOpen)
{
actionBarTitle.setText(gNavDrawerTitle);
}
else if(gSection == SECTION_HISTORY)
{
actionBarTitle.setText(gSectionTitle);
}
else
{
actionBarTitle.setText("");
}
}
}
(I use a custom ActionBar layout so I can't just use getActionBar().setTitle()
.)
You'll notice I have a Log.i()
in that function - here's what it says when the Navigation Drawer has been opened (as in that first picture):
navDrawerOpen: true, section: 1, section title: gSho
And here's what it says when it gets called after rotation (as in the second picture):
navDrawerOpen: false, section: 1, section title: History
As you can see, the Navigation Drawer remains open but the app thinks that it's been closed, so it restored the currently visible section's title. I followed the Navigation Drawer tutorial and I remembered to setup onPostCreate()
and onConfigurationChanged()
:
@Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
gNavDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
gNavDrawerToggle.onConfigurationChanged(newConfig);
}
And there's nothing special here, but here's my ActionBarDrawerToggle
all the same:
// Change the ActionBar whenever the drawer is opened or closed
gNavDrawerToggle = new ActionBarDrawerToggle(this, gNavDrawerLayout, R.drawable.ic_drawer, R.string.app_name, R.string.app_name)
{
@Override
public void onDrawerOpened(View drawerView)
{
// As per navigation drawer guidelines, show the app name and hide elements on the ActionBar
setTitle(gNavDrawerTitle);
invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View drawerView)
{
setTitle(gSectionTitle);
// Show hidden Action Bar elements
invalidateOptionsMenu();
}
};
The above code works fine until I rotate my device, at which point the wrong title is restored to the ActionBar because it thinks the Navigation Drawer is closed when it's still open. What am I doing wrong here?
Solución
You're calling it before the DrawerLayout
has had enough time to layout. You could call View.post
on your DrawerLayout
then log it in the Runnable
.
Otros consejos
Try adding calls to super.onDrawerClosed()
and super.onDrawerOpened()
like so:
// Change the ActionBar whenever the drawer is opened or closed
gNavDrawerToggle = new ActionBarDrawerToggle(this, gNavDrawerLayout, R.drawable.ic_drawer, R.string.app_name, R.string.app_name)
{
@Override
public void onDrawerOpened(View drawerView)
{
super.onDrawerOpened(drawerView);
// As per navigation drawer guidelines, show the app name and hide elements on the ActionBar
setTitle(gNavDrawerTitle);
invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View drawerView)
{
super.onDrawerClosed(drawerView);
setTitle(gSectionTitle);
// Show hidden Action Bar elements
invalidateOptionsMenu();
}
};
Try to add this to your activity AndroidManifest.xml. This avoid your activity restarts when you rotate the device. Also when you hide the keyboard and when the screen size changes.
android:configChanges="keyboardHidden|orientation|screenSize"