Animate drawer icon into arrow on setDisplayHomeAsUpEnabled?
Solution 1
I haven't tested this, but you may be able to achieve this by animating a float between 0 (drawer closed) and 1 (drawer open) and then passing the value into ActionBarDrawerToggle.onDrawerSlide(View, float)
. I believe that's how the toggle determines what state the animated toggle should be in.
Something like this should work.
ValueAnimator anim = ValueAnimator.ofFloat(start, end);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float slideOffset = (Float) valueAnimator.getAnimatedValue();
toolbarDrawerToggle.onDrawerSlide(drawerLayout, slideOffset);
}
});
anim.setInterpolator(new DecelerateInterpolator());
// You can change this duration to more closely match that of the default animation.
anim.setDuration(500);
anim.start();
Solution 2
Since the question was asked, an alternative way has become available. The animated arrow is implemented by the now public class DrawerArrowDrawable
which implements Drawable
.
In your code, set the navigation icon as follows:
DrawerArrowDrawable drawerArrow = new DrawerArrowDrawable(this);
drawerArrow.setColor(myColor);
toolbar.setNavigationIcon(drawerArrow);
Register an OnBackStackChangedListener
and animate the arrow manually:
@Override
public void onBackStackChanged() {
boolean drawer = getSupportFragmentManager().getBackStackEntryCount() == 0;
ObjectAnimator.ofFloat(drawerArrow, "progress", drawer ? 0 : 1).start();
}
Vextil
Updated on August 17, 2020Comments
-
Vextil almost 4 years
I'm using setDisplayHomeAsUpEnabled in order to show the arrow instead of the drawer "burger" icon but it's not getting animated or anything. Instead it shows the arrow drawable instantaneously.
Home screen: (Album 1)
When you tap a movie: (Album 2)
The thing is, the icon does the animation just fine when I slide the drawer, which makes me think that maybe I'm not supposed to use setDisplayHomeAsUpEnabled for this: (Album 3)
Album: http://imgur.com/a/LkXbh
Here's my drawer toggle code:
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar); setSupportActionBar(toolbar); drawerAdapter = new DrawerAdapter(this, App.getNavItems(), getSupportFragmentManager()); drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); drawerList = (ExpandableListView) findViewById(R.id.left_drawer); // Set onGroupClick and onChildClick drawerAdapter.setClickEvents(MainActivity.this, drawerLayout, drawerList); drawerList.setAdapter(drawerAdapter); ActionBarDrawerToggle toolbarDrawerToggle = new ActionBarDrawerToggle( this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close ) { public void onDrawerClosed(View view) { super.onDrawerClosed(view); invalidateOptionsMenu(); } public void onDrawerOpened(View view) { super.onDrawerOpened(view); invalidateOptionsMenu(); } }; drawerLayout.setDrawerListener(toolbarDrawerToggle); toolbarDrawerToggle.syncState();
EDIT: I want the animation not when opening the drawer, that works already. I would like to manually trigger the animation when I load a specific fragment. I may not have explained myself correctly.
-
Vextil over 9 yearsI have the material theme and the ActionBarDrawerToggle is the one from v7. Is there a way to change the icon to an arrow animating it programatically then? I want the animation not when opening the drawer, that works already. I would like to manually trigger the animation when I load a specific fragment. I may not have explained myself correctly.
-
Philio over 9 yearsIn that case you could use
setDisplayHomeAsUpEnabled(true)
and you would get a back arrow rather than a hamburger, but if you still have the nav drawer active then I don't think that's really as it's intended to work. If you check the Google apps that have been updated to the material theme you won't find any screens with a back arrow and an active nav drawer. -
Philio over 9 yearsFrom a UX perspective, user expects: There is a hamburger = there is a nav drawer. There is a back arrow = go back to the previous screen.
-
Vextil over 9 yearsThat's true, and I understand that the user does not expect a drawer when there's an arrow. The thing is, my idea was to lock the drawer and show a back arrow because I wanted to avoid creating a new activity which allows me to transition the movie poster from the previous fragment into the new one with the new animation APIs and change the Toolbar background color smoothly.
-
Philio over 9 yearsSounds like that should work. Add new fragment, add to back stack, show back arrow, lock the drawer. Then when back is pressed change back to a hamburger and enable the drawer again.
-
Vextil over 9 yearsThere's still no way to animate the hamburger into an arrow right?
-
Nathan Walters over 9 years@Philio "If you check the Google apps that have been updated to the material theme you won't find any screens with a back arrow and an active nav drawer." That's blatantly false. Click on an app in the Play Store to open its details activity: the back arrow is displayed, but you can still swipe in the nav drawer. Joaquin is asking how to trigger the hamburger->arrow animation manually.
-
Philio over 9 yearsAh I see what you mean, I don't know of a way to animate the hamburger into a back arrow.
-
Nathan Walters over 9 years@Philio it works for me on both Play Games, Play Store, and Play Music. What version of Android are you running?
-
Philio over 9 yearsI restarted the phone and actually the nav drawer is working now as you suggested in all the Google apps. Strange! In fact in Play Music, it's messed up and when you're in a details activity you still get close animations and the hamburger jumps back to an arrow :)
-
Vextil over 9 yearsI cant, I need 15 reputation sorry :(
-
Raveesh Bhalla over 9 yearsThis works perfectly. Just set start=0 and end=1 to go from hamburger to arrow, and start=1 and end=0 for arrow to hamburger. One thing you'll have to keep track of is when the drawer is closed when the arrow is shown. At this point, the hamburger ends up being shown (because of the drawer's slide), which you'll have to correct.
-
russellhoff over 9 yearsThis works prefectly when you click on the icon to open it and to close it. It also works when you slide the drawer either to open it or to close it. But, what I miss is the effect shown when you slide the drawer, i.e. the transition. How can I reproduce it? Here you can see the transition between hamburger to arrow youtube.com/watch?v=D8U-FKSrGVs, and here after implementing your solution youtube.com/watch?v=abvi8gHzHkU
-
Nathan Walters over 9 years@russellhoff if you post that as a new question with some of your code, I may be able to help you.
-
russellhoff over 9 years@NathanWalters here it's the question stackoverflow.com/questions/27187312/…. Thanks!
-
Sotti over 9 yearsThis was it to me. Thanks
-
Tejas Sherdiwala about 9 yearsWorks like a charm. Thank you.
-
Eurig Jones almost 9 years@NathanWalters This works when going from back button to hamburger whilst using setDisplayHomeAsUpEnabled(false), but it doesn't work the other way around even if I swap 0, 1 start, end. Any idea how this could be done?
-
Javier Delgado over 8 yearsWhich is the class that has the onBackStackChanged() method?
-
Kirill Rakhman over 8 yearsThe interface
OnBackStackChangedListener
has that method: developer.android.com/intl/es/reference/android/app/… Used with developer.android.com/intl/es/reference/android/app/… -
jlively over 6 yearsWhat's
drawer
in this case? -
Kirill Rakhman over 6 years@jlively all the required code is included.
boolean drawer
indicates whether the drawable should display the hamburger or the back arrow.