2010-11-27 62 views
23

我寫了一個自定義View。現在我想在用戶觸摸時做一些自定義動畫。Android中的自定義動畫

當我說自定義時,我的意思是我基​​本上想要自己渲染每個幀,並且而不是使用「預定義」動畫,如描述的here

執行此操作的正確方法是什麼?

+0

[自定義動畫中的Android(http://www.singhajit.com/android-custom-animations/) – 2016-04-16 12:47:00

+0

@AjitSingh,該文章描述了標準的動畫(旋轉,平移等)。我在這裏問的是自定義動畫。 – aioobe 2016-04-16 15:00:36

回答

22

創建自定義動畫最靈活(也是相當容易)的方法是擴展Animation類。

一般:

  1. 使用setDuration()方法動畫的設定時間段。
  2. 可以選擇使用setInterpolator()(用於exapmle可以使用LinearInterpolatorAccelerateInterpolator等)
  3. 覆蓋applyTransformation方法設置的插補器動畫。在這裏,我們對interpolatedTime變量感興趣,該變量在0.0和1.0之間變化並表示您的動畫進度。

下面是一個例子(我使用這個類來改變ofsset Bitmap本身被吸入draw方法我Bitmap的。):

public class SlideAnimation extends Animation { 

    private static final float SPEED = 0.5f; 

    private float mStart; 
    private float mEnd; 

    public SlideAnimation(float fromX, float toX) { 
     mStart = fromX; 
     mEnd = toX; 

     setInterpolator(new LinearInterpolator()); 

     float duration = Math.abs(mEnd - mStart)/SPEED; 
     setDuration((long) duration); 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     super.applyTransformation(interpolatedTime, t); 

     float offset = (mEnd - mStart) * interpolatedTime + mStart; 
     mOffset = (int) offset; 
     postInvalidate(); 
    } 

} 

您也可以通過使用Transformation#getMatrix()修改View

UPDATE

在,如果你使用的是Android動畫框架(或兼容的實現 - NineOldAndroids)的情況下,你可以只需要聲明的setter和getter爲您定製View財產,直接製作動畫。以下是另一個示例:

public class MyView extends View { 

    private int propertyName = 50; 

    /* your code */ 

    public int getPropertyName() { 
     return propertyName; 
    } 

    public void setPropertyName(int propertyName) { 
     this.propertyName = propertyName; 
    } 

    /* 
    There is no need to declare method for your animation, you 
    can, of course, freely do it outside of this class. I'm including code 
    here just for simplicity of answer. 
    */ 
    public void animateProperty() { 
     ObjectAnimator.ofInt(this, "propertyName", 123).start(); 
    } 

} 
-1

除了定義XML中的補間動畫,您還可以定義逐幀動畫(存儲在res/drawable中)。

<animation-list 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:oneshot="true" 
> 
    <item android:drawable="@drawable/frame1" android:duration="300" /> 
    <item android:drawable="@drawable/frame2" android:duration="300" /> 
    <item android:drawable="@drawable/frame3" android:duration="300" /> 
</animation-list> 

通過setBackgroundResource將動畫設置爲View背景。

如果您想要做更復雜的事情,請參閱Canvas課程。請參閱關於如何draw with Canvas的簡要介紹。

+1

他想渲染程序中的每一幀。 – dacwe 2010-11-28 10:35:13

+0

嗯......動畫取決於組件被按下的位置...... – aioobe 2010-11-28 17:10:33

2
Animation animation = new AnimationDrawable(); 
animation.addFrame(getResources().getDrawable(R.drawable.exp1), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp2), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp3), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp4), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp5), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp6), 50); 

這是我用來在我的onCreate()中生成自定義逐幀動畫的代碼。

之後,我需要啓動動畫,但必須在UI線程內進行。因此我使用Runnable。

class Starter implements Runnable { 
    public void run() { 
     animation.stop(); 
     animation.start(); 
    } 
} 

我開始,使用的ImageView的.POST()方法從一個onClick可運行():

((ImageView) findViewById(R.id.ImageToAnimateOnClicking)).post(new Starter()); 
+0

看起來不錯。以編程方式渲染這些drawable是否可行? (動畫取決於用戶點擊的位置......) – aioobe 2010-11-29 07:00:52

+0

'AnimationDrawable''動畫'可以通過setBackgroundResource設置爲View背景。你也可以找到簡單的方法來確定它與絕對覆蓋。可能取決於用戶點擊的位置! (在按鈕上?表面視圖?圖像?列表視圖?) – 2010-12-04 22:02:05

1

我假定所創建的每個幀作爲一個位圖,然後把它傳遞給動畫直接,而不是從資源獲取Drawable。

Bitmap bm = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_888); 
Canvas c = new Canvas(bm); 
.... Draw to bitmap 
animation.addFrame(bm,50) 
.... repeat for all frames you wish to add. 
0

有四種類型的動畫可以添加到自定義視圖中。

  1. α - 動畫元件的透明度
  2. 翻譯 - 動畫元件的位置
  3. 規模 - 動畫元件的尺寸
  4. 旋轉 - 動畫元件的旋轉

這裏是一個blog post其詳細解釋每一個。

一旦完成創建動畫,只需使用下面的代碼將該自定義動畫添加到視圖。

findById(R.id.element).startAnimation(AnimationUtils.loadAnimation(this, R.anim.custom_animation));