Can I open the drawer layout with animation programmatically?

前端 未结 3 547
孤城傲影
孤城傲影 2020-12-09 16:24

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

相关标签:
3条回答
  • 2020-12-09 17:22

    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.

    0 讨论(0)
  • 2020-12-09 17:27

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

    0 讨论(0)
  • 2020-12-09 17:29

    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.

    0 讨论(0)
提交回复
热议问题