刷新菜单项动画ActionBarSherlock

问题描述:

public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 

    case android.R.id.home: 
     return true; 

    case R.id.searchIcon: 
     return true; 

    case R.id.startRefresh: 
     refreshItem = item; 
     refresh(); 
     return true; 
    case R.id.stopRefresh: 

     if (refreshItem != null && refreshItem.getActionView() != null) { 
      refreshItem.getActionView().clearAnimation(); 
      refreshItem.setActionView(null); 
     } 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 


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

后再点击:刷新菜单项动画ActionBarSherlock

enter image description here

点击后:

enter image description here

下面的图标被动画(旋转)。

问题:

为什么它转移到左侧?

一旦转移到左侧,图标变得不点击的,奇怪的设备后退按钮也不起作用

编辑:

在此应答下面的评论:

Animated Icon for ActionItem

杰克沃顿说,如果你正在使用一个正方形和正确大小的图标的菜单项,你不会得到这种奇怪的行为,对有同样的pr的人oblem。

但我在使用mdpi drawables的设备上使用32x32图像。这是说要有工作:(

谢谢

编辑:

refresh_action_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    style="@style/Widget.Sherlock.ActionButton" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/ic_refresh" /> 

自定义样式我在应用程序中使用

<style name="My_solid_ActionBar" parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse"> 
    <item name="background">@drawable/ab_solid_My</item> 
    <item name="backgroundStacked">@drawable/ab_stacked_solid_My</item> 
    <item name="backgroundSplit">@drawable/ab_bottom_solid_My</item> 
    <item name="progressBarStyle">@style/My_ProgressBar</item> 
    <item name="android:background">@drawable/ab_solid_My</item> 
    <item name="android:backgroundStacked">@drawable/ab_stacked_solid_My</item> 
    <item name="android:backgroundSplit">@drawable/ab_bottom_solid_My</item> 
    <item name="android:progressBarStyle">@style/My_ProgressBar</item> 
</style> 
+0

FWIW,这里是一个项目展示你想要的效果,如果它给你任何想法:https://github.com/commonsguy/cw-omnibus/tree/master/Progress/ActionBar – CommonsWare

+0

是的,我用你的代码甚至现在进度条(设置为ActionView)向左移动,并且其他菜单项都不起作用。 –

+0

你应该发布一个完整的示例项目来演示你的问题。如果在我上面链接的示例中,我会''始终',并且第一个操作栏项目,我的'刷新'仍然有效,而不会显示您描述的行为。 – CommonsWare

问题是你没有处理onCreateOptionsMenu()中的所有菜单通货膨胀。 ActionBar刷新动画的基本逻辑是我在开源应用程序中看到的例如Andlytics(也用于项目中),在onCreateOptionsMenu()中实现boolean标志来决定是否显示刷新动画。

您可以实现这样的:当你的refresh()方法被调用,它设置booleanisRefreshing标志设置为true,并调用inValidateOptionsMenu()其“幕后”调用onCreateOptionsMenu()启动动画:

充气菜单onCreateOptionsMenu(...)

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    menu.clear(); 
    super.onCreateOptionsMenu(menu, inflater); 
    //inflate a menu which shows the non-animated refresh icon 
    inflater.inflate(R.menu.my_ab_menu, menu); 

    if (isRefreshing) { 
     //if we're refreshing, show the animation 
     MenuItem item = menu.findItem(R.id.refreshMenuItem); 
     item.setActionView(R.layout.action_bar_indeterminate_progress); 
     ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView); 
     ((AnimationDrawable) iv.getDrawable()).start(); 
    } 
} 

开始动画像这样:

public void refresh(){ 
     isRefreshing = true; 
     inValidateOptionsMenu(); 
    } 

如果你希望用户时,他拿出刷新图标启动动画,做这样的onOptionsItemSelected()

case R.id.refreshMenuItem: 
    isRefreshing = true; 
    item.setActionView(R.layout.action_bar_indeterminate_progress); 
    ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView); 
    ((AnimationDrawable) iv.getDrawable()).start(); 
    //... 

停止动画电话:

isRefreshing = false; 
invalidateOptionsMenu(); 

此代码是从Fragment所以你可能需要调整,如果对于Activity,但我认为它传达了基本的想法。

+0

但在我看到的所有例子中,那里没有什么像** invalidateOptionsMenu(); **。就像我在问题中所举的例子以及CommonsWare在评论中发布的那样。尽管会尝试这个。 –

+0

有不同的方法可以达到同样的效果。我发现这种方法很容易理解和调试。看看Andlytics的应用示例。你可以从市场上下载它,看看它是如何作为一个真实世界的例子。 –

+0

我已经编辑了答案,以显示如何处理用户启动的刷新,而不是仅以编程方式启动刷新动画。你必须添加检查它是否已经动画,当用户点击等... –

我试着使用完全相同的代码,它对我来说工作得很好。这可能是不同的唯一事情是两件事情:

1)refresh_action_view布局(这里是我比较):

<?xml version="1.0" encoding="utf-8"?> 
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    style="?attr/actionButtonStyle" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/ic_menu_refresh" /> 

2)你的动作条的显示选项(这是我的styles.xml比较)。

<resources> 

<style name="AppTheme" parent="Theme.Sherlock.Light.DarkActionBar"> 
    <item name="android:actionBarStyle">@style/Widget.ActionBar</item> 
    <item name="actionBarStyle">@style/Widget.ActionBar</item> 
</style> 

<style name="Widget.ActionBar" parent="Widget.Sherlock.Light.ActionBar.Solid.Inverse"> 
    <item name="android:displayOptions">showHome|useLogo|showCustom</item> 
    <item name="displayOptions">showHome|useLogo|showCustom</item> 
</style> 

</resources> 

你能分享你的吗?

+0

是的done.please检查编辑部分 –