2010-11-27 64 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));