首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ActionItem的动画图标

ActionItem的动画图标
EN

Stack Overflow用户
提问于 2012-03-16 11:51:14
回答 7查看 66.1K关注 0票数 91

我一直在到处寻找我的问题的适当解决方案,但我似乎还找不到。我有一个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时,我希望图标开始动画,更具体地说,是在适当的位置旋转。有问题的图标是刷新图标。

我意识到ActionBar支持使用自定义视图(Adding an Action View),但是这个自定义视图被扩展到覆盖整个ActionBar区域,并且实际上阻止了除应用程序图标之外的所有东西,在我的例子中,这不是我想要的。

因此,我的下一个尝试是尝试使用AnimationDrawable并逐帧定义我的动画,将可绘制设置为菜单项的图标,然后在onOptionsItemSelected(MenuItem item)中获取图标并开始使用((AnimationDrawable)item.getIcon()).start()进行动画。然而,这并不成功。有没有人知道有什么方法可以达到这个效果?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-03-16 13:09:54

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

首先,他们定义了一个动画XML:

<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
 }

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

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

你就完事了!

以下是要做的其他事情:

  • 缓存动作视图布局膨胀和动画膨胀。它们速度较慢,因此您只需执行一次。
  • completeRefresh()

中添加null校验

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

票数 176
EN

Stack Overflow用户

发布于 2013-01-16 22:45:00

我在使用ActionBarSherlock的解决方案上做了一些工作,我想出了这个:

res/layout/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/layout-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/drawable/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);
    }
}

活动创建菜单项中的

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

和图标,this is drawable-xhdpi/ic_menu_navigation_refresh.png

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

票数 16
EN

Stack Overflow用户

发布于 2014-02-20 00:08:55

除了杰克·沃顿所说的之外,您还应该执行以下操作,以确保动画平滑停止,并且不会在加载完成后立即跳过

首先,创建一个新的布尔值(用于整个类):

private boolean isCurrentlyLoading;

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

isCurrentlyLoading = true;

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

isCurrentlyLoading = false;

在动画上设置AnimationListener:

animationRotate.setAnimationListener(new AnimationListener() {

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

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

这样,动画只有在已经旋转到结束时才能停止,并且将在短时间内重复,并且不再加载。

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

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9731602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档