Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animated menu item "jumps" when animation starts

I am using the code from this question: Animated Icon for ActionItem to animate my refresh ActionBarButton. It works fine, except that the style doesn't seem to be right. When I click the item, it starts rotating, but only after it "jumps" a few pixels. It seems like the style of the ImageView is different from the style of the menu item.

The item is defined like this:

<item
    android:id="@+id/action_refresh"
    android:orderInCategory="100"
    android:icon="@drawable/ic_menu_refresh"
    android:showAsAction="ifRoom"

    <!-- added this myself, didn't have any effect -->
    style="@android:style/Widget.ActionButton"  
    android:title="@string/action_refresh"/>

and the ImageView like this:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@string/action_refresh"
    android:src="@drawable/ic_menu_refresh"
    style="@android:style/Widget.ActionButton" />

How can I style my menuitem to match the ImageView in the rotation, or the other way round?

like image 328
Bart Friederichs Avatar asked Oct 02 '13 14:10

Bart Friederichs


3 Answers

I found the solution by setting the View also for the non-animated item to be the same. In the menu.xml:

<item
    android:id="@+id/action_refresh"
    android:orderInCategory="100"
    android:icon="@drawable/ic_menu_refresh"
    android:actionLayout="@layout/refresh_action_view"
    android:showAsAction="ifRoom"
    style="@android:style/Widget.ActionButton"
    android:title="@string/action_refresh"/>

Then, in onCreateOptionsMenu, I fetch the view in a member variable, and attach an onclick handler:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.orders, menu);
    final Menu m = menu;
    refreshItem = menu.findItem(R.id.action_refresh);
    refreshItem.getActionView().setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {   
                        m.performIdentifierAction(refreshItem.getItemId(), 0);
                    }
            });
    return true;
}

In onCreate, we load the animation:

    rotation = AnimationUtils.loadAnimation(this, R.anim.clockwise_refresh);
    rotation.setRepeatCount(Animation.INFINITE);

Finally, call this to start the animation:

refreshItem.getActionView().startAnimation(rotation);

and this to stop it:

refreshItem.getActionView().clearAnimation();
like image 94
Bart Friederichs Avatar answered Nov 12 '22 13:11

Bart Friederichs


It's better to change the ImageView to an ImageButton, and not to change the layout on the menu item in menu.xml, then the image will not jump, and you also don't need to add the click handler. It will also be the correct size, which will not be the case if you use an ImageView instead of an ImageButton.

This is all you need:

<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/action_refresh"
android:src="@drawable/ic_menu_refresh"
android:id="@+id/refresh_view"
style="@android:style/Widget.ActionButton" />
like image 45
David Mold Avatar answered Nov 12 '22 11:11

David Mold


Put some padding in ImageView. In my case, 8dp on each side.

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingRight="8dp"
    android:paddingLeft="8dp"
    android:src="@drawable/ic_action_important" />
like image 1
Azam Avatar answered Nov 12 '22 13:11

Azam