Android NavigationView MenuItem Icon Animation

I'm trying to figure out if menu animation animations should work in the new Navigationview, just like animating action elements or any other view that is used in any application layout.

The code below does not work for me. I use to test the sample code released by Android for the new support library. The same animation code works well on the toolbar. Also tried the older API for animation (after this link: Animated icon for ActionItem )

I think I missed something ...

thanks.

code:

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; 
+5
source share
1 answer

It is possible. You do not need to set a custom view for this.

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

We cannot animate drawable directly, so use DrawableWrapper (from android.support.v7 for API <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; } } 

I took the idea for DrawableWrapper from here: fooobar.com/questions/64039 / ...

0
source

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


All Articles