2012-02-09 92 views
17

有什麼辦法可以同時動畫多個視圖嗎?單動畫 - 多視圖

我想要做的是翻譯的動畫:

我有5個TextViews和4條彩色(普通RelativeLayouts與背景)。在動畫開始時,stipt與TextViews水平放置在一起。最後我想堆積條之間的所有TextViews:

enter image description here

這是一個非常簡單的繪圖,但它說明了我想做的事情。有什麼辦法可以用動畫做到這一點,還是我必須使用畫布動畫。

回答

4

創建您的動畫對象,然後在所有視圖上同時使用startAnimation。因此,這將是這樣的:

TranslateAnimation anim1; 
TranslateAnimation anim2; 
TranslateAnimation anim3; 

// Setup the animation objects 

public void startAnimations() 
{ 
    //... collect view objects 
    view1.startAnimation(anim1); 
    view2.startAnimation(anim2); 
    view3.startAnimation(anim3); 
} 

只要注意的是,更多的動畫,你已經在一次回事,慢這將是。

+1

這會不會導致他們不同步(非必需這裏)特別是那些以後開始的? – Matthew 2012-02-09 19:58:36

+0

不是。基本上,當你在一個視圖上使用'startAnimation'時,會發生無效,直到它到達所需的位置。當您一次調用所有視圖時,它們都會自己調用'invalidate()',然後在下一個繪製過程中,每個視圖將在其下一個框架中繪製。既然你在UI線程上調用了所有這些,那麼在你從這個方法返回之前,沒有任何動畫會啓動。注意:使用預蜂窩動畫框架只會移動視圖的可視部分。用戶將無法點擊它。 – DeeV 2012-02-09 20:10:03

+0

我使用anim1.setFillAfter(true)應用動畫;然後通過使用佈局參數實際移動視圖? (我應該嘗試一下,但已經晚了:) – Matthew 2012-02-09 20:19:53

3

我設法在多個視圖中共享一個動畫實例。至少用AlphaAnimation。我有一個ListView和一個應該應用於所有列表項視圖的特定子項的動畫。就我而言,視圖應該有可能隨時「共享」和「保留」共享動畫,並且不應以任何方式影響其他動畫視圖,也不應干擾已經運行的動畫。 爲了達到這個目的,我不得不做一個Android的股票AlphaAnimation的調整副本。 我的用例比較特殊,但爲了防止有人需要使用ListView處理類似的目標,請將其放在這裏。

/** 
* This class is a copy of android's stock AlphaAnimation with two adjustments: 
* - fromAlpha, toAlpha and duration are settable at any time. 
* - reset() method can be blocked. Reason: view.setAnimation() calls animation's reset() method 
* which is not intended in our use case. 
* For every new list item view we call setAnimation once for it's life time 
* and animation should not be reset because it is shared by all list item views and may be in progress. 
*/ 
public class MutableAlphaAnimation extends Animation { 
    private float mFromAlpha; 
    private float mToAlpha; 
    private boolean resetBlocked; 

    public MutableAlphaAnimation() { 
    } 

    public void start(float fromAlpha, float toAlpha, long duration) { 
     mFromAlpha = fromAlpha; 
     mToAlpha = toAlpha; 
     setDuration(duration); 
     setStartTime(START_ON_FIRST_FRAME); 
    } 

    public void setResetBlocked(boolean resetBlocked) { 
     this.resetBlocked = resetBlocked; 
    } 

    @Override 
    public void reset() { 
     if (! resetBlocked) super.reset(); 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     final float alpha = mFromAlpha; 
     t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime)); 
    } 

    @Override 
    public boolean willChangeTransformationMatrix() { 
     return false; 
    } 

    @Override 
    public boolean willChangeBounds() { 
     return false; 
    } 
} 

爲了這個動畫設置爲一個觀點:

  animation.setResetBlocked(true); 
      view.setAnimation(animation); 
      animation.setResetBlocked(false); 

,並開始動畫(先前由setAnimation設置)兩件事情必須做到:

 animation.start(0.0f, 1.0f, FADE_IN_DURATION); 

之後,你必須在受動畫影響的每個視圖上手動調用invalidate()。

通常的startAnimation()會爲你無效(),但setAnimation不會。 (閱讀Android的源View.setAnimation()方法的評論)。

49

可以使用ObjectAnimator製作動畫的多重看法如下:

ArrayList<ObjectAnimator> arrayListObjectAnimators = new ArrayList<ObjectAnimator>(); //ArrayList of ObjectAnimators 

ObjectAnimator animY = ObjectAnimator.ofFloat(view, "y", 100f); 
arrayListObjectAnimators.add(animY); 

ObjectAnimator animX = ObjectAnimator.ofFloat(view, "x", 0f); 
arrayListObjectAnimators.add(animX); 
... 
ObjectAnimator[] objectAnimators = arrayListObjectAnimators.toArray(new ObjectAnimator[arrayListObjectAnimators.size()]); 
AnimatorSet animSetXY = new AnimatorSet(); 
animSetXY.playTogether(objectAnimators); 
animSetXY.setDuration(1000);//1sec 
animSetXY.start(); 
+2

唯一的缺點是,它是自版本11以來的新版本(蜂窩) – Matthew 2013-01-13 17:03:49

+3

使用nineoldandroids將API一路帶回到1.0(http://nineoldandroids.com/) – Tushar 2013-02-15 02:55:17

+0

+1以顯示如何將它們一起啓動 – 2014-07-29 17:26:31

0

您可以使用AnimationSet

AnimatorSet decSet2 = new AnimatorSet(); 
     decSet2.playTogether(
       ObjectAnimator.ofFloat(view, "x",dX), 
       ObjectAnimator.ofFloat(view, "y",dY), 
       ObjectAnimator.ofFloat(mTextCancel, "x",dX), 
       ObjectAnimator.ofFloat(mTextCancel, "y", dY), 
       ObjectAnimator.ofArgb(mBtnOne, "visibility", View.VISIBLE, View.GONE), 
       ); 
     decSet2.setDuration(0); 
     decSet2.start();