android – Can I open the drawer layout with animation programmatically?-ThrowExceptions

Exception or error:

I created the app drawer by using the following library:
http://developer.android.com/training/implementing-navigation/nav-drawer.html

I want to show the Navigation Drawer with animation when opening the app.
How can I do that?

How to solve:

Predraw listener, aka the safeway

Here is the predraw listener example. It will literally start the animation as soon as it can which maybe a little too fast. You might want to do a combination of this with a runnable shown second. I will not show the two combined, only separate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // Building NavDrawer logic here. Just a method call would be best.
    ...

    ViewTreeObserver vto = drawer.getViewTreeObserver();
    if (vto != null) vto.addOnPreDrawListener(new ShouldShowListener(drawer));
}

private static class ShouldShowListener implements OnPreDrawListener {

    private final DrawerLayout drawerLayout;

    private ShouldShowListener(DrawerLayout drawerLayout) {
        this.drawerLayout= drawerLayout;
    }

    @Override
    public boolean onPreDraw() {
        if (view != null) {
            ViewTreeObserver vto = view.getViewTreeObserver();
            if (vto != null) {
                vto.removeOnPreDrawListener(this);
            }
        }

        drawerLayout.openDrawer(Gravity.LEFT);
        return true;
    }
}

PostDelay Runnable, aka living dangerous

// Delay is in milliseconds
static final int DRAWER_DELAY = 200;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // Building NavDrawer logic here. Just a method call would be best.
    ...
    new Handler().postDelayed(openDrawerRunnable(), DRAWER_DELAY);
}

private Runnable openDrawerRunnable() {
    return new Runnable() {

        @Override
        public void run() {
            drawerLayout.openDrawer(Gravity.LEFT);
        }
    }
}

WARNING

If they rotate on the start of the app for the first time BOOM! Read this blog post for more information http://corner.squareup.com/2013/12/android-main-thread-2.html. Best thing to do would be to use the predraw listener or remove your runnable in onPause.

###

You can call openDrawer(int gravity) on the DrawerLayout to make it open the drawer with an animation.

###

You need to call drawerLayout.openDrawer(Gravity.LEFT) to animate the drawer opening. The drawer won’t animate if you make the call too early in the Activity lifecycle.

The simplest solution is to just set a flag in onCreate() and act on it in onResume().

You want to make sure that you only set the flag when savedInstanceState is null indicating that the Activity isn’t being resumed from the background. You don’t want the drawer sliding out every time you change orientation or switch applications.

public class MainActivity extends ActionBarActivity {
    private DrawerLayout drawerLayout;
    private boolean firstResume = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawerLayout = (DrawerLayout)findViewById(R.id.drawer);

        if(savedInstanceState == null){
            firstResume = true;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if(firstResume) {
            drawerLayout.openDrawer(Gravity.LEFT);
        }

        firstResume = false;
    }
}

You could also use an OnPreDrawListener but I feel it’s a bit unnecessarily complicated as onPreDraw is called multiple times so you need to remove the listener after opening the drawer. You’re also assuming that preDraw is a suitable time to activate the drawer which is an internal implementation of the drawer layout. A future implementation might not animate properly until after onDraw for example.

Delaying the drawer opening by an arbitrary number of milliseconds is a dangerous way to solve this problem. In the worst case the call to open the drawer could happen after onDestroy if the user navigates away quickly.

Leave a Reply

Your email address will not be published. Required fields are marked *