Android NavigationView MenuItem图标动画

时间:2015-11-28 23:26:29

标签: android animation

我试图了解菜单图标动画是否适用于新版本 导航视图,与动作项动画相同的方式或任何其他视图,用于任何应用程序布局。

以下代码对我不起作用。 我用它来测试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>

drawer_view:

<?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 个答案:

答案 0 :(得分:0)

有可能。您不需要为此设置自定义视图。

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();
}

我们无法直接为drawable制作动画,因此请使用DrawableWrapper(来自android.support.v7 for API&lt; 21):

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://stackoverflow.com/a/39108111/5541688