安卓NavigationView菜单项图标动画

5
我正在试图理解菜单图标动画是否应该在新的NavigationView中工作,就像操作项动画或任何其他视图一样,这些视图用于任何应用程序布局。
下面的代码对我来说无法正常工作。我正在使用Android发布的支持库代码示例进行测试。相同的动画代码在工具栏上运行得很好。也尝试了旧的API进行动画(遵循此链接:Animated Icon for ActionItem
我想我错过了什么...
提前致谢。
代码:
Xml:
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true"
    android:background="@color/lightPrimaryColor">

    <include layout="@layout/include_list_viewpager"/>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        android:background="@color/lightPrimaryColor"
        app:headerLayout="@layout/nav_header"
        app:theme="@style/menu_item_style"
        app:menu="@menu/drawer_view"/>

</android.support.v4.widget.DrawerLayout>

抽屉视图:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:class="http://schemas.android.com/tools"
    class:actionViewClass="android.widget.ProgressBar">

    <group android:checkableBehavior="single"
        android:id="@+id/drawer_menu">
        <!--   <item
           android:id="@+id/nav_my_lists"
           android:title="@string/title_shopping_lists"
           android:icon="@drawable/ic_event"
           app:showAsAction="always"/> -->
        <item
            android:id="@+id/nav_examp_lists"
            android:icon="@drawable/refresh1"
            android:title="@string/example"
            app:showAsAction="always"
            android:layoutDirection="rtl"/>
        <item
            android:id="@+id/nav_split_lists"
            android:title="@string/split"
            android:icon="@drawable/refresh2"
            app:showAsAction="always"
            app:actionViewClass="android.widget.ImageView"/>
        <item
            android:id="@+id/nav_change_net"
            android:title="@string/change"
            android:icon="@drawable/refresh3"
            app:showAsAction="always"
            android:layoutDirection="rtl"/>

    </group>

</menu>

Java:

navigationView.setNavigationItemSelectedListener(
                new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {

               menuItem.setChecked(true);
               mDrawerLayout.closeDrawers();

                switch (menuItem.getItemId()) {

                    case R.id.nav_my_lists:

                        anim = AnimatorInflater.loadAnimator(getApplication(), R.animator.rotation);
                        anim.setTarget(menuItem.getIcon());
                        anim.setDuration(2000);
                        //anim.setStartDelay(10);
                        anim.addListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationStart(Animator animation) {
                                Toast.makeText(getApplication(), "Started...", Toast.LENGTH_SHORT).show();
                            }

                        });

                        anim.start();
                        boolean run = anim.isRunning();

                        String title = menuItem.getTitle().toString();
                        loadShoppingList(title);

                        return true;
1个回答

1

这是可能的。你不需要为此设置自定义视图。

private AnimationDrawableWrapper drawableWrapper;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //...

    Menu menu = navigationView.getMenu();
    MenuItem menuItem = menu.findItem(R.id.your_icon);
    Drawable icon = menuItem.getIcon();
    drawableWrapper = new AnimationDrawableWrapper(getResources(), icon);
    menuItem.setIcon(drawableWrapper);
}

public void startRotateIconAnimation() {
    ValueAnimator animator = ObjectAnimator.ofInt(0, 360);
    animator.addUpdateListener(animation -> {
        int rotation = (int) animation.getAnimatedValue();
        drawableWrapper.setRotation(rotation);
    });
    animator.start();
}

我们无法直接对可绘制对象进行动画处理,因此请使用DrawableWrapper(适用于API<21的android.support.v7):

public class AnimationDrawableWrapper extends DrawableWrapper {

    private float rotation;
    private Rect bounds;

    public AnimationDrawableWrapper(Resources resources, Drawable drawable) {
        super(vectorToBitmapDrawableIfNeeded(resources, drawable));
        bounds = new Rect();
    }

    @Override
    public void draw(Canvas canvas) {
        copyBounds(bounds);
        canvas.save();
        canvas.rotate(rotation, bounds.centerX(), bounds.centerY());
        super.draw(canvas);
        canvas.restore();
    }

    public void setRotation(float degrees) {
        this.rotation = degrees % 360;
        invalidateSelf();
    }

    /**
     * Workaround for issues related to vector drawables rotation and scaling:
     * https://code.google.com/p/android/issues/detail?id=192413
     * https://code.google.com/p/android/issues/detail?id=208453
     */
    private static Drawable vectorToBitmapDrawableIfNeeded(Resources resources, Drawable drawable) {
        if (drawable instanceof VectorDrawable) {
            Bitmap b = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(b);
            drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
            drawable.draw(c);
            drawable = new BitmapDrawable(resources, b);
        }
        return drawable;
    }
}

我从这里得到了DrawableWrapper的想法:https://dev59.com/sm865IYBdhLWcg3wceRU#39108111

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接