Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate ActionBarDrawerToggle icon programmatically

I want to animate the drawer icon from a burger to an arrow and vice versa manually, not only when drawer is being dragged, is it possible? I'm using support library appcompat-v7:21.

Also I can't find the source code of android.support.v7.app.ActionBarDrawerToggle which would helpful.

like image 576
Ivan Fork Avatar asked Oct 21 '14 05:10

Ivan Fork


Video Answer


2 Answers

I found a way to animate the icon with a simple ValueAnimator and .onDrawerSlide method.

    ValueAnimator anim = ValueAnimator.ofFloat(start, end);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            float slideOffset = (Float) valueAnimator.getAnimatedValue();
            drawerToggle.onDrawerSlide(drawerLayout, slideOffset);
        }
    });
    anim.setInterpolator(new DecelerateInterpolator());
    anim.setDuration(300);
    anim.start();

But maybe there is a better solution.

like image 136
Ivan Fork Avatar answered Sep 28 '22 03:09

Ivan Fork


// define your drawer layout
    DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    // define your actionbar toggle
    final ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            // Pass in context
            this,
            // Pass in your drawer layout
            drawerLayout,
            // Pass a String resource to describe the "open drawer" action for accessibility
            R.string.open_drawer,
            // Pass a String resource to describe the "close drawer" action for accessibility
            R.string.close_drawer
    );
    // add a drawerListener to your drawer layout
    drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            // Here's where the animation happens.
            // the provided float starts at 0 (drawer closed) and goes to 1 (drawer open) hitting all points in between.

            // ActionBarDrawerToggle has an onDrawerSlide method that takes your drawer layout and the provided float from the onDrawerSlide constructor.
            // By passing the slideOffSet from the drawer's OnDrawerSlide method into the toggle, it maps the animation to the provided float.
            toggle.onDrawerSlide(drawerView, slideOffset);
        }

        @Override
        public void onDrawerOpened(View view) {

        }

        @Override
        public void onDrawerClosed(View view) {

        }

        @Override
        public void onDrawerStateChanged(int i) {

        }
    });

EDIT: The above will work, but I found a much more elegant way to do this. By setting the toggle as the drawer's listener, the states are handled by default. See below:

        // define your drawer layout
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    // define your actionbar drawertoggle
    drawerToggle = new ActionBarDrawerToggle(
            // Pass in context
            this,
            // Pass in your drawer layout
            drawerLayout,
            // Attach the toolbar
            toolbar,
            // Pass a String resource to describe the "open drawer" action for accessibility
            R.string.open_drawer,
            // Pass a String resource to describe the "close drawer" action for accessibility
            R.string.close_drawer
    )  {
        // attach drawer listener states to the ActionBarDrawerToggle
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
            invalidateOptionsMenu();
        }

        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            invalidateOptionsMenu();
        }
    };
    drawerLayout.setDrawerListener(drawerToggle);
    drawerToggle.syncState();
like image 43
Psest328 Avatar answered Sep 28 '22 02:09

Psest328