2012-04-07 141 views
4

我在啓動AsyncTask的ActionBarSherlock操作欄中有一個菜單選項。我試圖在後臺任務運行時讓圖標變成動畫。我有它的工作,除了當我點擊圖標時,圖標本身會向右「跳」幾個像素,這是非常明顯的。不完全確定是什麼原因導致發生。ActionBarSherlock動畫移動位置

這是我到目前爲止有:

private MenuItem refreshItem; 

private void DoRefresh() 
{ 
    final LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    final ImageView ivRefresh = (ImageView)inflater.inflate(R.layout.refresh_view, null); 

    final Animation rotation = AnimationUtils.loadAnimation(activity, R.anim.refresh); 
    ImageView ivRefresh.startAnimation(rotation); 

    refreshItem.setActionView(ivRefresh); 

    //AsyncTask is kicked off here 
} 

@Override 
public boolean onOptionsItemSelected(final MenuItem item) 
{ 
    if (item.getItemId() == R.id.refresh) { 
     refreshItem = item; 
     this.DoRefresh(); 
     return true; 
    } else { 
     return super.onOptionsItemSelected(item); 
    } 
} 

refresh_view.xml

<?xml version="1.0" encoding="utf-8"?> 

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:src="@drawable/refresh" 
/> 

refresh.xml

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

UPDATE:

愚弄AR因此,沒有運氣。它與動畫無關,因爲如果我禁用動畫,圖標仍會跳轉到右側。如果我註釋掉setActionView,圖標不會跳轉,所以它與此有關。毫無頭緒,讓我瘋狂。

+0

你應該看看[這裏] [1]。 [1]:http://stackoverflow.com/questions/9935875/changing-view-on-menu-item-in-action-bar – Trivial 2012-04-12 20:24:15

+0

我已經創建的圖標,並解決了換檔問題。如果有人感興趣:http://stackoverflow.com/a/14360958/492624 – 2013-01-16 14:49:53

回答

-1

如果菜單選項是一個操作項目,則應該將樣式Widget.Sherlock.ActionButton應用於ImageView以保持一致性。閱讀這篇文章,我寫了如何正確地爲動作項設置動畫。 http://alexfu.tumblr.com/post/19414506327/android-dev-animate-action-items

+0

上帝保佑你,就是這樣! – 2012-04-14 14:10:49

+0

鏈接在哪裏? – 2014-01-27 15:02:33

0

我不知道這是否會產生任何效果,但是如果您使用pivot值,您可能會解決此問題。也許只能在一個軸上旋轉?

0

你應該看看here。它對我來說非常合適。

+0

您是否使用ImageView作爲動畫圖標?你介意發佈你的佈局代碼嗎? – 2012-04-13 18:25:40

0

Alex Fu,你的文章非常有幫助,但是可以做一些改進。

每次在onAnimationEnd中重新啓動動畫效率不高。相反,在動畫開始前將動畫repeatcount設置爲無限,然後當動作完成時,將repeatcount設置爲0.動畫將完成當前循環,然後調用onAnimationEnd,您可以在其中調用setActionView(null)。

我也遇到了一個問題(至少在模擬器中,沒有在真實設備上測試過,因爲我沒有一個)同時使用ActionBarSherlock和本地ICS ActionBar,最後幾幀調用setActionView(null)後動畫與靜態按鈕重疊。我的解決方案是包裝在LinearLayout中動畫的ImageView,然後在LinearLayout上調用setVisibility(View.GONE)。如果爲視圖設置動畫,使用setVisibility隱藏視圖將不起作用,但會隱藏其父視圖。

這裏的所有相關代碼:

佈局/ actionbar_progress.xml(請注意,我添加的ID,雖然只有ImageView的需要之一):

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/actionbar_progress_container" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" > 

    <ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/actionbar_progress_image" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:padding="5dp" 
     android:src="@drawable/ic_action_refresh" 
     style="@style/Widget.Sherlock.ActionButton" 
     /> 
</LinearLayout> 

動畫/ refresh_rotate.xml:

<?xml version="1.0" encoding="utf-8"?> 
<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" 
    android:repeatCount="infinite"> 

</rotate> 

repeatCount設置爲無限,但這不是必需的,因爲java代碼必須將其設置爲無限大。

在onCreateOptionsMenu我

... 
menuInflater.inflate(R.menu.main, menu); 

mRefreshItem = menu.findItem(R.id.menu_refresh); 
... 

這只是避免做每一個刷新按鈕被點擊時,則findItem。

在onOptionsItemSelected:

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

    ... 

     case R.id.menu_refresh: 
      refresh(); 
      break; 

    ... 

    } 
} 

刷新方法僅僅是一個虛擬5秒延遲交;它調用refreshAnim啓動動畫,然後refreshAnimEnd當它完成停止動畫:

private void refresh() { 
    refreshAnim(); 
    getWindow().getDecorView().postDelayed(
     new Runnable() { 
      @Override 
      public void run() { 
       refreshAnimEnd(); 
      } 
     }, 5000); 
} 

這裏是最重要的部分,搭配點評:

​​
+0

'每次在動畫結束時重新開始動畫效率不高。相反,在動畫開始前將動畫repeatcount設置爲無限,然後當動作完成時,將repeatcount設置爲0.動畫將完成當前循環,然後調用onAnimationEnd,您可以在其中調用setActionView(null).' - 這是一個好主意,我在寫這篇文章時沒有想到。感謝您的意見。 – 2012-06-25 18:07:53

0

只需添加到您的img_layout

style="?android:attr/actionButtonStyle" 

或者這與福爾摩斯動作條:如果你使用的是正常的動作條.XML

style="@style/Widget.Sherlock.ActionButton"