Navigation drawer icons (hamburger & arrow) animat

2020-07-18 05:10发布

问题:

I'm using AppCompat and Toolbar.

I ensure there will be animation, when the navigation drawer icon transits from hamburger to arrow, or vice-verse.

I use the following technique https://stackoverflow.com/a/26469738/72437

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    </style>

    <style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
        <item name="spinBars">true</item>
        <item name="color">@android:color/white</item>
    </style>

</resources>

Animation happens when I press the navigation drawer, to slide in & slide out the menu. However, it isn't very useful. As according to material design guideline, the navigation drawer fragment should be full height. Hence, it will block the navigation drawer icon, when it starts to slide out.

I'm more interested to perform animation, when dealing with my search button (action_search), which acts as action view of my toolbar.

main_menu.xml

<item android:id="@+id/action_search"
    android:title="Search me"
    android:icon="@drawable/ic_add_white_24dp"
    app:showAsAction="always|collapseActionView"
    app:actionLayout="@layout/collapsible_searchtext" />

<item android:id="@+id/action_settings" android:title="@string/action_settings"
    android:orderInCategory="100" app:showAsAction="never" />

collapsible_searchtext.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    >
    <android.widget.AutoCompleteTextView
        android:id="@+id/search"
        android:dropDownWidth="match_parent"
        android:completionThreshold="1"
        android:inputType="textNoSuggestions"
        android:imeOptions="actionSearch|flagNoExtractUi"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:singleLine="true"
        android:hint="Search stock"
        android:layout_gravity="center_vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>
  1. When I press action_search, the search icon will expand to AutoCompleteTextView. At the same time, hamburger icon will animate to arrow icon
  2. When I press arrow icon, arrow icon will animate back to hamburger icon.

I try to achieve objective 1, by using the following code after reading https://stackoverflow.com/a/26480439/72437

private void animateHamburgerToArrow() {
    ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            float slideOffset = (Float) valueAnimator.getAnimatedValue();
            actionBarDrawerToggle.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();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        animateHamburgerToArrow();
        return true;
    } else if (id == R.id.action_search) {
        animateHamburgerToArrow();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

When I press action_search, hamburger icon does change to arrow icon. However, there's no animation. May I know is there anything I had missed?

Update

I suspect that, the left arrow used by navigation drawer, is different from the left arrow used by search action view. They are 2 different instances.

This is because if I click action_settings, I can observe the animation. However, if I click action_search, I will not observe the animation. I suspect the left arrow used by search action view, "block" navigation drawer's icons (both hamburger & arrow)

回答1:

I achieved this effect without unrolling my own custom SearchView. The thing is, there are really two separate buttons for burger and back arrow. So, while we can access the burger button with the public method setHomeAsUpIndicator(), the back button can only be reached with reflection. Then we just set the desired drawable on it as well, and play the animation on both button drawables simultaneously irrespective of whether the specific button is visble or not. This works as both buttons are positioned exactly in the same position in the layout.

For details see the post http://choruscode.blogspot.com/2015/09/morphing-animation-for-toolbar-back.html