ActionItem的animation图标

我一直在寻找一个妥善解决我的问题,我似乎无法find一个呢。 我有一个ActionBar(ActionBarSherlock)与一个XML文件充气的菜单,该菜单包含一个项目,并且一个项目显示为一个ActionItem。

菜单:

<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_refresh" android:icon="@drawable/ic_menu_refresh" android:showAsAction="ifRoom" android:title="Refresh"/> </menu> 

活动:

 [...] @Override public boolean onCreateOptionsMenu(Menu menu) { getSupportMenuInflater().inflate(R.menu.mymenu, menu); return true; } [...] 

ActionItem是显示一个图标,没有文字,但是当用户点击ActionItem时,我希望图标开始animation,更具体地说,旋转就位。 有问题的图标是刷新图标。

我意识到ActionBar支持使用自定义视图( 添加一个操作视图 ),但是这个自定义视图被扩大到覆盖整个ActionBar区域,实际上阻止了除了应用程序图标之外的所有东西,在我的情况下,这不是我正在寻找。

所以我的下一个尝试是尝试使用AnimationDrawable并逐帧定义我的animation,将drawable设置为菜单项的图标,然后在onOptionsItemSelected(MenuItem item)获取图标并使用((AnimationDrawable)item.getIcon()).start() 。 然而这是不成功的。 有谁知道有什么办法来达到这个效果?

你在正确的轨道上。 这里是GitHub Gaug.es应用程序将如何实现它。

首先他们定义一个animationXML:

 <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="1000" android:interpolator="@android:anim/linear_interpolator" /> 

现在为动作视图定义一个布局:

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

我们所需要做的就是在该项目被点击时启用这个视图:

  public void refresh() { /* Attach a rotating ImageView to the refresh item as an ActionView */ LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); ImageView iv = (ImageView) inflater.inflate(R.layout.refresh_action_view, null); Animation rotation = AnimationUtils.loadAnimation(getActivity(), R.anim.clockwise_refresh); rotation.setRepeatCount(Animation.INFINITE); iv.startAnimation(rotation); refreshItem.setActionView(iv); //TODO trigger loading } 

加载完成后,只需停止animation并清除视图:

 public void completeRefresh() { refreshItem.getActionView().clearAnimation(); refreshItem.setActionView(null); } 

你完成了!

一些额外的事情要做:

  • caching动作视图布局通货膨胀和animation通货膨胀。 他们很慢,所以你只想做一次。
  • completeRefresh()添加null检查

这是对应用程序的拉请求: https : //github.com/github/gauges-android/pull/13/files

我已经使用ActionBarSherlock解决了一些问题,我想出了这个:

RES /布局/ indeterminate_progress_action.xml

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="48dp" android:layout_height="wrap_content" android:gravity="center" android:paddingRight="12dp" > <ProgressBar style="@style/Widget.Sherlock.ProgressBar" android:layout_width="44dp" android:layout_height="32dp" android:layout_gravity="left" android:layout_marginLeft="12dp" android:indeterminate="true" android:indeterminateDrawable="@drawable/rotation_refresh" android:paddingRight="12dp" /> </FrameLayout> 

RES /布局-V11 / indeterminate_progress_action.xml

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" > <ProgressBar style="@style/Widget.Sherlock.ProgressBar" android:layout_width="32dp" android:layout_gravity="left" android:layout_marginRight="12dp" android:layout_marginLeft="12dp" android:layout_height="32dp" android:indeterminateDrawable="@drawable/rotation_refresh" android:indeterminate="true" /> </FrameLayout> 

RES /抽拉/ rotation_refresh.xml

 <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:pivotX="50%" android:pivotY="50%" android:drawable="@drawable/ic_menu_navigation_refresh" android:repeatCount="infinite" > </rotate> 

代码中的活动(我有它在ActivityWithRefresh父类)

 // Helper methods protected MenuItem refreshItem = null; protected void setRefreshItem(MenuItem item) { refreshItem = item; } protected void stopRefresh() { if (refreshItem != null) { refreshItem.setActionView(null); } } protected void runRefresh() { if (refreshItem != null) { refreshItem.setActionView(R.layout.indeterminate_progress_action); } } 

在活动创build菜单项

 private static final int MENU_REFRESH = 1; @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(Menu.NONE, MENU_REFRESH, Menu.NONE, "Refresh data") .setIcon(R.drawable.ic_menu_navigation_refresh) .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS); setRefreshItem(menu.findItem(MENU_REFRESH)); refreshData(); return super.onCreateOptionsMenu(menu); } private void refreshData(){ runRefresh(); // work with your data // for animation to work properly, make AsyncTask to refresh your data // or delegate work anyhow to another thread // If you'll have work at UI thread, animation might not work at all stopRefresh(); } 

而图标,这是drawable-xhdpi/ic_menu_navigation_refresh.png
可绘制-xhdpi / ic_menu_navigation_refresh.png

这可以在http://developer.android.com/design/downloads/index.html#action-bar-icon-pack

除了杰克·沃顿(Jake Wharton)所说的之外,你应该做一下以下的事情,确保animation能够平稳地停下来, 并且一旦装载完成就不会跳转

首先,创build一个新的布尔(对于整个class级):

 private boolean isCurrentlyLoading; 

find开始加载的方法。 活动开始加载时,将布尔值设置为true。

 isCurrentlyLoading = true; 

查找加载完成时启动的方法。 而不是清除animation,将您的布尔值设置为false。

 isCurrentlyLoading = false; 

在animation上设置一个AnimationListener:

 animationRotate.setAnimationListener(new AnimationListener() { 

然后,每次animation执行一次,这意味着当你的图标旋转一圈,检查加载状态,如果不加载,animation将停止。

 @Override public void onAnimationRepeat(Animation animation) { if(!isCurrentlyLoading) { refreshItem.getActionView().clearAnimation(); refreshItem.setActionView(null); } } 

这样,animation只有在已经旋转到最后才会被停止,并且会很快重复,并且不再被加载。

这至less是我想要实现杰克的想法时所做的。

还有一个选项可以在代码中创build轮换。 完整的剪辑:

  MenuItem item = getToolbar().getMenu().findItem(Menu.FIRST); if (item == null) return; // define the animation for rotation Animation animation = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setDuration(1000); //animRotate = AnimationUtils.loadAnimation(this, R.anim.rotation); animation.setRepeatCount(Animation.INFINITE); ImageView imageView = new ImageView(this); imageView.setImageDrawable(UIHelper.getIcon(this, MMEXIconFont.Icon.mmx_refresh)); imageView.startAnimation(animation); item.setActionView(imageView);