Android 5.0 - Animate the AppCompat v7 21 home icon icon from the burger to back arrow programmatically

I am currently updating a Fragment oriented application (I have one Activity with a FrameLayout container as the host for all my Fragment s) for Material Design. And I would like to animate the hamburger icon on the back arrow when replacing Fragment .

In principle, if this was not clear enough, here is what I want to achieve. I do not want to use this library (MaterialMenu) , I would like to use the official AppCompat lib to the extent possible.

I achieved this effect thanks to this solution , but I cannot figure out how to make the ActionBarDrawerToggle as the inverse when replacing the Fragment .

So my questions are: should the back arrow icon have an ActionBarDrawerToggle after replacing the Fragement ? In which case, how do I redefine it to act like onBackPressed() instead of opening a box? I already tried this, but it does not work:

  @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: getActivity().onBackPressed(); return true; } return false; } 

Thanks in advance.

+6
source share
3 answers

I think it's a little cleaner to keep track of the inside of the drawer switch if you manually opened it or not. This is what I ended up with:

 public class ManualActionBarDrawerToggle extends ActionBarDrawerToggle { private static final float MENU_POSITION = 0f; private static final float ARROW_POSITION = 1.0f; private final int animationLength; private final DrawerLayout drawerLayout; private final Activity activity; private State currentState; private enum State { UP_ARROW, MENU } public ManualActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, int openDrawerContentDescriptionResource, int closeDrawerContentDescriptionResource) { super(activity, drawerLayout, openDrawerContentDescriptionResource, closeDrawerContentDescriptionResource); animationLength = activity.getResources().getInteger(android.R.integer.config_shortAnimTime); this.drawerLayout = drawerLayout; this.activity = activity; currentState = State.MENU; } public void animateToBackArrow() { ValueAnimator anim = ValueAnimator.ofFloat(MENU_POSITION, ARROW_POSITION); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float slideOffset = (Float) valueAnimator.getAnimatedValue(); onDrawerSlide(drawerLayout, slideOffset); } }); anim.setInterpolator(new DecelerateInterpolator()); anim.setDuration(animationLength); anim.start(); currentState = State.UP_ARROW; } public void animateToMenu() { ValueAnimator anim = ValueAnimator.ofFloat(ARROW_POSITION, MENU_POSITION); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float slideOffset = (Float) valueAnimator.getAnimatedValue(); onDrawerSlide(drawerLayout, slideOffset); } }); anim.setInterpolator(new DecelerateInterpolator()); anim.setDuration(animationLength); anim.start(); currentState = State.MENU; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case (android.R.id.home): if (currentState == State.UP_ARROW) { activity.onBackPressed(); return true; } } return super.onOptionsItemSelected(item); } } 
+7
source

The menu available for this library has a method that can animate states:

If you want to switch from Burger to Arrow , you will make this call:

 mMaterialMenu.animateState(IconState.ARROW); 
+1
source

OK, so I understood the way. I am pretty sure this is NOT a good solution, as I use ActionBarDrawerToggle for a different purpose than what it was created for.

But it works, so that’s what I did. I just created a custom ActionBarDrawerToggle in which I override the onOptionsItemSelected(...) method:

 class MyDrawerToggle extends ActionBarDrawerToggle { // ... Default constructors matching super go here @Override public boolean onOptionsItemSelected(MenuItem item) { // If the back stack isn't empty, ie if I'm not in a Fragment // accessible from the NavigationDrawer, I simulate the onBackPressed behaviour if (getFragmentManager().getBackStackEntryCount() != 0) { onBackPressed(); return true; } return super.onOptionsItemSelected(item); } } 

If anyone has a better solution, please feel free to suggest.

+1
source

Source: https://habr.com/ru/post/977726/


All Articles