2012-11-24 50 views
10
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

回答

8

問題是你沒有處理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

我已經編輯了答案,以顯示如何處理用戶啓動的刷新,而不是僅以編程方式啓動刷新動畫。你必須添加檢查它是否已經動畫,當用戶點擊等... –

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檢查編輯部分 –