Skip to content Skip to sidebar Skip to footer

Transition Animation From Hamburger To Arrow Icon On Adding Fragment

I have implemented master/detail flow and I would like to get transition animation from hamburger icon to arrow icon after adding fragment (the same animation as when opening navig

Solution 1:

Some explanations first.

  1. android.support.v7.app.ActionBarDrawerToggle uses special drawable class for hamburger-to-arrow icons and animation.

  2. the class is android.support.v7.graphics.drawable.DrawerArrowDrawable

  3. DrawerArrowDrawable implements animation with method setProgress(float progress), where progress is from 0 (hamburger) to 1 (arrow).

  4. ActionBarDrawerToggle uses private void setPosition(float position) that calls DrawerArrowDrawable.setProgress()

  5. ActionBarDrawerToggle uses public void onDrawerSlide(View drawerView, float slideOffset) to call private setPosition()

  6. ActionBarDrawerToggle calls toolbar.setNavigationOnClickListener() in constructor with it's listener, that is used to toggle drawer.

  7. ActionBarDrawerToggle keep track of actual DrawerArrowDrawable state. Toolbar and ActionBar do not track actual DrawerArrowDrawable state.

So, what you should do in activity. Option-A, use ActionBarDrawerToggle.

// define a variable to track hamburger-arrow stateprotectedboolean isHomeAsUp = false;

    protectedDrawerLayout drawer;
    protectedToolbar toolbar;
    protectedActionBarDrawerToggle toggle;

    // I've implemented it in setContentView(), but you can implement it in onCreate()@OverridepublicvoidsetContentView(@LayoutRes int layoutResID) {
        super.setContentView(layoutResID);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        toggle = newActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        // overwrite Navigation OnClickListener that is set by ActionBarDrawerToggle
        toolbar.setNavigationOnClickListener(newView.OnClickListener() {
            @OverridepublicvoidonClick(View v) {
                if (drawer.isDrawerOpen(GravityCompat.START)){
                    drawer.closeDrawer(GravityCompat.START);
                } elseif (isHomeAsUp){
                    onBackPressed();
                } else {
                    drawer.openDrawer(GravityCompat.START);
                }
            }
        });
    }

    // call this method for animation between hamburged and arrowprotectedvoidsetHomeAsUp(boolean isHomeAsUp){
        if (this.isHomeAsUp != isHomeAsUp) {
            this.isHomeAsUp = isHomeAsUp;

            ValueAnimator anim = isHomeAsUp ? ValueAnimator.ofFloat(0, 1) : ValueAnimator.ofFloat(1, 0);
            anim.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
                @OverridepublicvoidonAnimationUpdate(ValueAnimator valueAnimator) {
                    float slideOffset = (Float) valueAnimator.getAnimatedValue();
                    toggle.onDrawerSlide(drawer, slideOffset);
                }
            });
            anim.setInterpolator(newDecelerateInterpolator());
            // You can change this duration to more closely match that of the default animation.
            anim.setDuration(400);
            anim.start();
        }
    }

Or you can set a DrawerArrowDrawable as a navigation icon with toolbar.setNavigationIcon() and animate it without ActionBarDrawerToggle See Option-B: https://stackoverflow.com/a/42024138/1148784

Solution 2:

See my another answer for explanation https://stackoverflow.com/a/42023946/1148784. This is option-B. code for Activity class. We do not use ActionBarDrawerToggle here.

protectedboolean isHomeAsUp = false;
    DrawerArrowDrawable homeDrawable;
    protectedToolbar toolbar;
    protectedDrawerLayout drawer;

    @OverridepublicvoidsetContentView(@LayoutRes int layoutResID) {
        super.setContentView(layoutResID);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawer = (DrawerLayout) findViewById(R.id.drawer_layout);

        homeDrawable = newDrawerArrowDrawable(toolbar.getContext());
        toolbar.setNavigationIcon(homeDrawable);

        toolbar.setNavigationOnClickListener(newView.OnClickListener() {
            @OverridepublicvoidonClick(View v) {
                if (drawer.isDrawerOpen(GravityCompat.START)){
                    drawer.closeDrawer(GravityCompat.START);
                } elseif (isHomeAsUp){
                    onBackPressed();
                } else {
                    drawer.openDrawer(GravityCompat.START);
                }
            }
        });
    }

    protectedvoidsetHomeAsUp(boolean isHomeAsUp){
        if (this.isHomeAsUp != isHomeAsUp) {
            this.isHomeAsUp = isHomeAsUp;
            ValueAnimator anim = isHomeAsUp ? ValueAnimator.ofFloat(0, 1) : ValueAnimator.ofFloat(1, 0);
            anim.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
                @OverridepublicvoidonAnimationUpdate(ValueAnimator valueAnimator) {
                    float slideOffset = (Float) valueAnimator.getAnimatedValue();
                    homeDrawable.setProgress(slideOffset);
                }
            });
            anim.setInterpolator(newDecelerateInterpolator());
            anim.setDuration(400);
            anim.start();
        }
    }

Post a Comment for "Transition Animation From Hamburger To Arrow Icon On Adding Fragment"