Skip to content Skip to sidebar Skip to footer

Appcompat V7 Toolbar Up/back Arrow Not Working

I have two fragments in an activity. When fragment A is showing, I want the navigation drawer burger icon to show and the navigation drawer to work. When fragment B is showing, I

Solution 1:

From what I have seen in the source code of v7 ActionBarDrawerToggle, you can animate the icon to different states without having the drawer being opened.

privateenumActionDrawableState{
        BURGER, ARROW
    }
    privatestaticvoidtoggleActionBarIcon(ActionDrawableState state, final ActionBarDrawerToggle toggle, boolean animate){
        if(animate) {
            floatstart= state == ActionDrawableState.BURGER ? 0f : 1.0f;
            floatend= Math.abs(start - 1);
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                ValueAnimatoroffsetAnimator= ValueAnimator.ofFloat(start, end);
                offsetAnimator.setDuration(300);
                offsetAnimator.setInterpolator(newAccelerateDecelerateInterpolator());
                offsetAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
                    @OverridepublicvoidonAnimationUpdate(ValueAnimator animation) {
                        floatoffset= (Float) animation.getAnimatedValue();
                        toggle.onDrawerSlide(null, offset);
                    }
                });
               offsetAnimator.start();
            }else{
                //do the same with nine-old-androids lib :)
            }
        }else{
            if(state == ActionDrawableState.BURGER){
                toggle.onDrawerClosed(null);
            }else{
                toggle.onDrawerOpened(null);
            }
        }
    }

Morphing between Burger and Arrow depends on values between 0f and 1.0f, basically these are values that the drawer passes to the ActionBarDrawerToggle.

I used ValueAnimator to animate values in this range, i.e mimicking the drawer toggling.

null arguments are safe because ActionBarDrawerToggle does not care at all about drawer views. Make sure you take a look at new interpolators to do the animation fully-by-the-book of material design guidelines:

fast_out_linear_in  
fast_out_slow_in

Another approach is to access mSlider private field of the ActionBarDrawer through reflection and call setPosition(float position) method to toggle between Burger and Arrow. mSlider is of type (extends) DrawerArrowDrawable.

Personally, I always try to avoid reflection, as long as there is no other way to do your dirty work.

Solution 2:

As Support Library updated to 23.0.0, there is a better way to play drawer-arrow animation. So I'm going to improve @Nikola's answer. Here's code:

publicstaticvoidplayDrawerToggleAnim(final DrawerArrowDrawable d) {
    floatstart= d.getProgress();
    floatend= Math.abs(start - 1);
    ValueAnimatoroffsetAnimator= ValueAnimator.ofFloat(start, end);
    offsetAnimator.setDuration(300);
    offsetAnimator.setInterpolator(newAccelerateDecelerateInterpolator());
    offsetAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
        @OverridepublicvoidonAnimationUpdate(ValueAnimator animation) {
            floatoffset= (Float) animation.getAnimatedValue();
            d.setProgress(offset);
        }
    });
    offsetAnimator.start();
}

And call it whenever you want by:

playDrawerToggleAnim((DrawerArrowDrawable) toolbar.getNavigationIcon());

Solution 3:

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        publicvoidonBackStackChanged() {
            int stackHeight = getSupportFragmentManager().getBackStackEntryCount();
            if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment)
                getSupportActionBar().setHomeButtonEnabled(true);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            } else {
                getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                getSupportActionBar().setHomeButtonEnabled(false);
            }
        }

    });

After ...

@OverridepublicbooleanonOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            getSupportFragmentManager().popBackStack();
            returntrue;
     ....
 }

Solution 4:

In my case the icon is animating: I have used ActionBarDrawerToggle v7.

MainActivity:

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

    setSupportActionBar(toolbar);
    toolbar.setTitle("ToolBar Demo");
    toolbar.setLogo(R.drawable.ic_launcher);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);

    mDrawerToggle = newActionBarDrawerToggle(this, mDrawerLayout, toolbar,
            R.string.open_navigation_drawer,
            R.string.close_navigation_drawer) {

        @OverridepublicvoidonDrawerSlide(View drawerView, float slideOffset) {
            // TODO Auto-generated method stubsuper.onDrawerSlide(drawerView, slideOffset);
        }

        /** Called when a drawer has settled in a completely closed state. */@OverridepublicvoidonDrawerClosed(View view) {
            super.onDrawerClosed(view);
            getSupportActionBar().setTitle("hello");
        }

        /** Called when a drawer has settled in a completely open state. */@OverridepublicvoidonDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            getSupportActionBar().setTitle("hi");
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);



}

@OverridepublicbooleanonOptionsItemSelected(MenuItem item) { // <---- addedif (mDrawerToggle.onOptionsItemSelected(item)) {
        returntrue;
    }
    returnsuper.onOptionsItemSelected(item);
}

@OverrideprotectedvoidonPostCreate(Bundle savedInstanceState) { // <---- addedsuper.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState(); // important statetment for drawer to// identify// its state
}

@OverridepublicvoidonConfigurationChanged(Configuration newConfig) { // <---- addedsuper.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@OverridepublicvoidonBackPressed() {
    if (mDrawerLayout.isDrawerOpen(Gravity.START | Gravity.LEFT)) { // <----// added
        mDrawerLayout.closeDrawers();
        return;
    }
    super.onBackPressed();
}

Post a Comment for "Appcompat V7 Toolbar Up/back Arrow Not Working"