Materialdrawer: Animate hamburger to a back arrow when opening a subfragment

Created on 5 Nov 2015  路  9Comments  路  Source: mikepenz/MaterialDrawer

I need following behaviour:

  • Drawer is only available for main fragment
  • Drawer is locked if a sub fragment is dispplayed
  • when changing the main fragment with the subfragent, I want to animate the hamburger to the arrow
  • I need to catch the home button click when a subfragment is shown

Following works fine with no animation, and works when opening a sub fragment, but not when going back. I know why it does not work, but I don't know if I can solve the problem with your library.

private void updateDrawerState(final Fragment f)
{
    final boolean isSubFragment = isSubFragment(f);
    boolean animate = true;

    if (!animate)
    {
        updateDrawerStateNoAnimate(f);
    }
    else
    {
        int from = isSubFragment ? 0 : 1;
        int to = isSubFragment ? 1 : 0;
        ValueAnimator anim = ValueAnimator.ofFloat(from, to);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float slideOffset = (Float) valueAnimator.getAnimatedValue();
                mDrawer.getActionBarDrawerToggle().onDrawerSlide(mDrawer.getDrawerLayout(), slideOffset);
            }
        });
        anim.addListener(new SimpleAnimatorListener() {
            @Override
            public void onAnimationEnd(Animator animator) {
                updateDrawerStateNoAnimate(f);
            }
        });
        anim.setInterpolator(new LinearInterpolator());
        anim.setDuration(500);
        anim.start();
    }
    mDrawer.getDrawerLayout().setDrawerLockMode(isSubFragment ? DrawerLayout.LOCK_MODE_LOCKED_CLOSED : DrawerLayout.LOCK_MODE_UNLOCKED);
}

private void updateDrawerStateNoAnimate(Fragment f)
{
    boolean isSubFragment = isSubFragment(f);
    if (isSubFragment)
    {
        mDrawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
    else
    {
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        mDrawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(true);
    }
}
question

Most helpful comment

You also have synced the state

this.mActionBarDrawerToggle.syncState();

and set the listeners:

mActionBarDrawerToggle.setToolbarNavigationClickListener(toolbarNavigationListener);
mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);

the MaterialDrawer does not do so much more for you:
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1319

All 9 comments

@MFlisar if you want you can manage the ActionBarDrawerToggle completely on your own without any interaction of the MaterialDrawer just do not provide the Toolbar via the builder and create the ActionBarDrawerToggle with the DrawerLayout which you can get via the getter of the Drawer object (which is created with .build())

I tried using it like you suggest, but I can't even get it to show an icon in the toolbar...

I comment out following:

//                .withToolbar(toolbar)
//                .withActionBarDrawerToggle(true)
//                .withActionBarDrawerToggleAnimated(true)

And replace it with following:

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    mToggle = new ActionBarDrawerToggle(this, mDrawer.getDrawerLayout(), toolbar, R.string.open, R.string.close);
    mToggle.setDrawerIndicatorEnabled(true);

But then the drawer icon is not visible....

I could not get it showing the indicator if I don't use the builder for it...

You also have synced the state

this.mActionBarDrawerToggle.syncState();

and set the listeners:

mActionBarDrawerToggle.setToolbarNavigationClickListener(toolbarNavigationListener);
mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);

the MaterialDrawer does not do so much more for you:
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1319

this is mostly for linking the toggle with the drawer layout, which I don't want anyway... And setting up click listeners. But I'm stuck before listening to events, as the hamburger nor the back arrow is showing in the toolbar... Your suggestions do not help, the icon is not visible even if I add them...

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToggle = new ActionBarDrawerToggle(this, mDrawer.getDrawerLayout(), toolbar, R.string.open, R.string.close);
mToggle.setDrawerIndicatorEnabled(true);
mToggle.syncState();
mToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

    }
});
mDrawer.getDrawerLayout().setDrawerListener(mToggle);

@MFlisar strange enough. As mentioned if you keep the default behavior the drawer only handles this internally to simplify everything. And if you don't provide a Toolbar i will keep this open to the dev.

Your drawer is already built at this time. So this can't be the cause

Perhaps something from here can help as it seems to be a Toolbar + ActionBarDrawerToggle issue: http://stackoverflow.com/questions/26863230/android-support-toolbar-actionbardrawertoggle-not-changing-to-arrow

Found the problem... I just oversaw that I initiliase setDisplayHomeAsUp at another place as well and this lead to the problem. This means, your first suggestion is working and is the solution for the problem. My second post, the 3 liner, is working as expected now. You just have to add the syncState statement although I only manually animate the icon... Thanks

@MFlisar great ;)

@Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
ObjectAnimator.ofFloat(actionBarDrawerToggle.getDrawerArrowDrawable(), "progress", 1).start();
}
else{
ObjectAnimator.ofFloat(actionBarDrawerToggle.getDrawerArrowDrawable(), "progress", 0).start();
}
}

@trung0123 This works great but how can i catch a click on the arrow? Setting setToolbarNavigationClickListener only detects clicks on the toolbar but not on the arrow.
Maybe @mikepenz does know an answer how to do this? I want to go back on the backstack when clicking the back arrow and not opening the drawer menu.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jd-alexander picture jd-alexander  路  4Comments

oleynikd picture oleynikd  路  4Comments

kakai248 picture kakai248  路  4Comments

y2kshane picture y2kshane  路  4Comments

Erwinstein picture Erwinstein  路  3Comments