Here's what's happening.. from my navigation drawer I select an item that then starts up a new activity. Now the thing is I want to close the navigation drawer before opening the new activity, but I don't want the delay to be too long so what I do is start the new activity with a postdelayed handler of about 200ms after a call to closeDrawer(). SO, the drawer is still closing when the new activity gets initialized. The problem kicks in when I go back to the original activity: the layout is shifted about halfway up the screen and tiled in a weird way. Doesn't seem to get fixed until you interact with it (so I'm assuming it gets fixed with the onDraw() call).
Conditions that make this crop up:
Device is in LANDSCAPE mode (doesn't happen on portrait)
The navigation drawer is animating out of view when startActivity() is called
Any insight? Bonus question: is there an easy way of making the navigation drawer close without the animation?
EDIT: Turns out the same thing happens if I'm in landscape and use startActivityForResult(). It's not an issue with only startActivity() though..
In your onAuthenticatedResume() of DrawerActivity, try configuring the DrawerManager & Toggle for drawer properly. The code looks like the snippet below ( I just added some dummy lines like 'YourDrawerManager' means whatever the manager you have )
#Override
protected void onAuthenticatedResume() {
super.onAuthenticatedResume();
//Configure NavigationDrawer
navigationDrawerManager = new YourDrawerManager();
mDrawerLayout = (DrawerLayout)findViewById(R.id.your_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.logo, "OK",
"Close") {
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(your_title_string));
supportInvalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
supportInvalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
}
I've figured out what the issue was.
The problem was that in my AndroidManifest.xml I declared the new activities as having screenOrientation="portrait" and only enabled orientation changes in the onCreate method for them if certain conditions were met.
I'm still not 100% clear on what was happening but it seems that the device would try to rotate to portrait on activity change, then go back to landscape before drawing the new activity (since it was enabled in onCreate) and then that somehow messed up the previous activity so that when I went back to it, it would get shifted weirdly.
Still an Android bug IMO, but at least I know what it stems from now.
Changed screenOrientation to "landscape" and it works fine now (this problem doesn't arise when the first activity is in portrait and the second is locked to landscape in the manifest... what???)
Related
When I use Material Drawer, as soon as a new activity starts, drawer is being displayed automatically, but I want that it starts hidden, so I have to use function drawer.closeDrawer() in the method onResume of activity, as described below:
#Override
protected void onResume() {
super.onResume();
drawer.closeDrawer();
}
Is this the correct way to hidden the drawer when activity starts or restarts, or there is a property to be set for this purpose in the drawer?
Thank you,
Alexandre Bianchi
There are different cases why the drawer may opens after the application starts.
Either you define withShowDrawerOnFirstLaunch, this should be removed or set to false, if you don't want this behavior.
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1188
It could also be that you open the drawer via the Drawer's API. So make sure you don't call openDrawer programtically
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/Drawer.java#L125
The Drawer comes also with a method to close the drawer. Just call closeDrawer
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/Drawer.java#L134
Put this code in oncreate and it will check the drawer is open or not...if its open it will close the drawer
DrawerLayout layout = (DrawerLayout) findViewById(R.id.drawer_layout);
if (layout.isDrawerOpen(GravityCompat.START)) {
layout.closeDrawer(GravityCompat.START);
}
I'm using a navigation drawer with fragments similar to the gmail app. But I am encountering two issues:
1: Suppose I select item x from the nav drawer. The corresponding fragment(fragment x) is displayed with no problem. However, when I change the orientation, the activity is recreated and fragment 1 (default fragment) is displayed , even though the navigation drawer shows item x as checked.
2: Again Suppose I select item x. Again the corresponding fragment(fragment x) is displayed with no problem. Now I close the app by pressing the home button and open up 10 other apps. After some time when I re-open my app, the activity is recreated and fragment 1 (default fragment) is displayed, even though the navigation drawer shows item x as checked.
Both the problems are similar and probably require the the same solution. How do I solve this?
In the Android Manifest, add
android:configChanges="keyboardHidden|orientation|screenSize"
This will stop the Activity from refreshing on such changes, including the case you mentioned, which is an orientation change.
For the Activity to resume after restoring from a minimised position, override the onPause and onResume methods in the Activity.
#Override public void onPause() {
super.onPause(); // Always call the superclass method first }
#Override public void onResume() {
super.onResume();
//Do the things you want to do }
For reference: https://developer.android.com/training/basics/activity-lifecycle/pausing.html
I have an activity with a DrawerLayout and a ActionBarDrawerToggle to handle a side menu.
Now, I needed this activity to rotate only on tablets but not on phone, so I added android:configChanges="orientation|..." to my manifest for that activity, and reimplemented onConfigurationChanged. On phones, nothing is done and portrait is forced, while on tablets, the new orientation is set to SCREEN_ORIENTATION_SENSOR to let the device decide and I reload the layout with setContentView().
Since I've done that, my side menu won't open past the first rotation. I discovered that onOptionsItemSelected is still called:
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == android.R.id.home) {
if (mDrawerLayout.isDrawerVisible(GravityCompat.START)) {
mDrawerLayout.closeDrawer(GravityCompat.START);
}
else {
mDrawerLayout.openDrawer(GravityCompat.START);
}
}
return true;
}
but the test that check if the drawer is visible always returns true.
Any idea on what could cause that? Did I forget to recreate or update something after the rotation in onConfigurationChanged?
Note: I also found out that if I don't recreate the layout (with setContentView()) the drawer works fine (but then I obviously lose the landscape layout and get the portrait layout somehow scaled)
So, I somehow found a solution to this, by reconnecting the DrawerLayout to the ActionBarDrawerToggle each time the device rotates, after recreating the layout:
setContentView(R.id.my_layout_id);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerLayout.setDrawerListener(mDrawerToggle);
in the onConfigurationChanged method.
The only downside to that is that the drawer won't keep its state between the two orientation (if it was opened, it'll be recreated and thus end up closed in the new orientation).
I have a Navigation Drawer (appcompat v7) in my app which is working perfectly fine.
Now I want to disable it, until the user buys an in-app-purchase to unlock additional functionality. So in my Activity.onCreate(), after initializing the drawer and populating it, I am calling this function:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
This function is not doing anything. The drawer continues to open and close as normal after tapping the drawer carat in the actionbar. I tried calling this function in Activity.onResume() without any difference.
What is the correct way to use this function?
(I tried looking online for answers, but couldn't find anything which addresses my issue). Any help is appreciated, as I am stuck on this issue for quite sometime now.
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
is only disabling the opening drawer layout by swiping till you click navigation drawer icon
keep a boolean variable
write mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); in onStart() and also write below lines of code
#Override
public boolean onOptionsItemSelected(android.view.MenuItem item) {
if(!disabled)
{
if (item.getItemId() == android.R.id.home) {
if (mDrawerLayout.isDrawerOpen(mDrawerLinearLayout)) {
mDrawerLayout.closeDrawer(mDrawerLinearLayout);
} else {
mDrawerLayout.openDrawer(mDrawerLinearLayout);
}
}
}
return super.onOptionsItemSelected(item);
}
this will work for sure
When you call setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) it locks opening and closing drawer only by swipes.
The drawer continues to open and close as normal after tapping the drawer carat in the action bar because your drawer will still respond to calls to openDrawer(int), closeDrawer(int) although a drawer is locked.
You need to add some logic in your action bar menu button listener and not to call openDrawer(int) when you don't want it to open.
Btw, it is okay to call setDrawerLockMode(int) in onŠ”reate
There is a bug with DrawerLayout and used gravity. I have reported it here:
https://issuetracker.google.com/issues/136738274
I implemented navigation drawer as described here in android developer portal.
And everything works fine. Now I read android guidlines here. In section "Introduce the user to the drawer at first use" there is described I should open the drawer when application launches first. Now my idea for implementing this is to open the drawer after opening the app (and maybe close it again).
Now I tried to call myDrawer.openDrawer(Gravity.LEFT) in onCreate and the drawer is open when the app launches, but there's no animation. So onCreate seems to be the wrong place. Where should I place the call to openDrawer to let the user see the animation?
I guess you can do this by delaying the animation. For example:
#Override
protected void onResume() {
super.onResume();
myDrawer.postDelayed(new Runnable() {
#Override
public void run() {
myDrawer.openDrawer(Gravity.LEFT)
}
}, 1000);
}
However the fact that the Android Guidelines suggests the drawer to be opened when the application launches for the first time, does not imply it should be animated.