Reputation: 1505
So I want to animate my DrawerLayout in such a way that it is opened, an item is added to the menu in it, then it is closed.
I tried a great deal of things, but the problem is that there is no delay between the "Open" and "Close" commands (or at least not a noticeable one) and so the animation never triggers.
I really don't want to use a 'post delayed' with an arbitrary length because that seems dirty. I've tried manually overriding "onDrawerOpened()" in the listener - which WORKED, but then I can't CLOSE it AFTER the action is performed because you can't close it from within itself (meaning, if the 'closeDrawer(layout)' method is invoked from any sub-thread of the listener itself, it'll get a runtime error).
So what I have is:
_drawerToggle = new ActionBarDrawerToggle(MainActivity.this, _drawerLayout, R.drawable.ic_drawer, R.string.drawerOpen, R.string.drawerClose)
{
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
getActionBar().setTitle(_title);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
myAction(); //My action
//If I try to invoke 'drawerClose()' here or in my action, a runtime error occurs
}
};
_drawerLayout.setDrawerListener(_drawerToggle);
_drawerLayout.openDrawer(_mainFrame);
//If I invoke 'drawerClose()' the entire thing is just too fast and the animations don't trigger
I even tried 'getAnimation()' on the DrawerLayout but it returns null so I can't use it to post a delayed action.
Anyone have an idea how to approach this? Should I just used an arbitrary delay and hope it looks the same on all devices? Is there a way to close the drawer from within the listener? Thanks in advance!
Upvotes: 0
Views: 7202
Reputation: 6771
Calling closeDrawer()
isn't working in onDrawerOpened()
because, well, the drawer hasn't finished opening. If you watch onDrawerStateChanged()
you'll notice the state still changes after onDrawerOpened()
is called.
I tried closing the drawer when onDrawerStateChanged()
said the drawer was idle, however it still crashed. My final solution looks, as you said, hacky. But it works, and looks smooth. This should be placed in onDrawerOpened()
new Thread() {
@Override
public void run() {
SystemClock.sleep(500);
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mDrawerLayout.closeDrawers();
}
});
}
}.start();
This could probably look a little better if you use some sort or thread manager, like the one posted here
https://gist.github.com/bclymer/6708605
Disclaimer, that's my utility class. I use it in most of my apps though, it's very convenient. With the utility the code would look like
ThreadManager.delayOnMainThread(new Runnable() {
@Override
public void run() {
mDrawerLayout.closeDrawers();
}
}, 500);
Upvotes: 5