View动画和Drawable动画

View动画

你可以使用view动画系统执行Views的补间动画。补间动画通过诸如起始点,终止点,大小,旋转,和一个动画其他通用的aspects等信息来计算动画。

一个补间动画可以在一个View对象的内容上执行一系列简单的变换(位置,大小,旋转,透明度)。因此,如果你有一个TextView对象,你可以移动,旋转,放大,或收缩文本。如果你有一个背景图片,则背景图片将随着文字而转换。animation包提供了用于一个补间动画的所有的类。

一系列的动画指令定义了补间动画,由XML或Android代码定义。至于定义一个layout,则建议用一个XML文件来定义,因为它相对于硬编码动画更可读,可复用,可交换。在下面的例子中,我们使用XML。(要学习更多在你的应用代码中定义一个动画而不是在XML中的方法,请参考AnimationSet及其他的Animation子类。)

动画指令定义了你想要执行的变换,何时执行变换,及它们应当执行多长时间。变换可以是串行的或并行的——比如,你可以使得一个TextView的内容自左向右移动,然后旋转180度,或你可以使文字的移动和旋转并行执行。每种变换需要一系列特定于变换的参数(大小变换的起始大小和结束大小,旋转的起始角度和结束角度,等等),及一系列的通用参数(比如,其实时间和持续时间)。要使多个变换并发执行,则提供给它们相同的起始时间;要使它们串行执行,则计算起始时间时加上前一个变换的持续时间。

动画XML文件应当放在你的Android工程的res/anim/目录下。文件必须有一个单独的根元素:这可能是一个单独的<alpha>,<scale>,<translate>,<rotate>,interpolator元素,或持有这些元素组的<set>元素(其中可以包含另一个<set>)。默认情况下,所有的动画指令是并发应用的。要使它们串行的发生,你必须执行startOffset属性,如下面的示例中显示的那样。

下面来自于一个ApiDemos的XML被用于伸展,然后并发地旋转,然后旋转一个View对象。

<set android:shareInterpolator="false">
    <scale
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromXScale="1.0"
        android:toXScale="1.4"
        android:fromYScale="1.0"
        android:toYScale="0.6"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fillAfter="false"
        android:duration="700" />
    <set android:interpolator="@android:anim/decelerate_interpolator">
        <scale
           android:fromXScale="1.4"
           android:toXScale="0.0"
           android:fromYScale="0.6"
           android:toYScale="0.0"
           android:pivotX="50%"
           android:pivotY="50%"
           android:startOffset="700"
           android:duration="400"
           android:fillBefore="false" />
        <rotate
           android:fromDegrees="0"
           android:toDegrees="-45"
           android:toYScale="0.0"
           android:pivotX="50%"
           android:pivotY="50%"
           android:startOffset="700"
           android:duration="400" />
    </set>
</set>

屏幕坐标系(没用于这个例子中)是(0,0)在左上角,向下和向右坐标逐渐变大。

一些值,比如pivotX,可以相对于对象本身或相对它的父对象来指定。要确保为你想要的效果使用了适当的格式("50"是相对于它的父对象50%,"50%"是相对于它本身50%)。

你可以通过分配一个Interpolator来决定如何随着时间应用一个转换。Android包含一些指定了各种速度曲线的Interpolator子类:比如,AccelerateInterpolator指示一个转换在开始时慢,然后加速。每一个都有一个可以应用于XML的属性值。

通过把这个XML命名为hyperspace_jump.xml并保存在项目的res/anim/目录中,,下面的代码可以引用它并将之应用于layout中的一个ImageView

ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);

startAnimation()的一个替代方法,你可以通过Animation.setStartTime()为动画定义一个起始时间,然后通过View.setAnimation()把动画分配给View。

更多关于XML语法,可用的tags,和属性的信息,请参见Animation Resources

注意:无论你的动画如何移动或改变大小,持有你的动画的View的边界将不会自动调整以适应它。甚至,动画在超出它的View范围内时依然绘制,而不裁剪。然而当动画超出父View的边界时,则将会被裁剪。

Drawable动画

Drawable动画使你能够通过一个接一个地加载一系列的Drawable资源来创建一个动画。严格说来,这是传统的动画,它由一系列不同的图片创建,然后顺序播放,就像一卷电影一样。AnimationDrawable类是Drawable动画的基础。

尽管你可以使用AnimationDrawable 在你的代码中定义一个动画的帧,但通过一个单独的列出了组成动画的帧的XML文件来完成更简单。这种动画的XML文件应该放在你的Android工程的res/drawable/目录下。在这种情况下,指令是动画每一帧的顺序和持续时间。

XML文件由一个<animation-list>作为根节点,及一系列定义了每一帧的子<item>节点组成:帧的drawable资源和帧的持续时间。这里有一个Drawable 动画的示例XML文件:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

这个动画只执行了3帧。通过把list的android:oneshot属性设置为true,它将只循环一次然后停留在最后一帧并一直保持那样的状态。如果它被设置为false,则动画将循环执行。通过把这个XML命名为rocket_thrust.xml,然后保存在工程的res/drawable/目录下,则它可以被以background图片的形式添加给一个View,然后调用play。这里有一个示例Activity,该动画被添加给其中的一个ImageView,然后在屏幕被touched时执行:

AnimationDrawable rocketAnimation;

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
}

public boolean onTouchEvent(MotionEvent event) {
  if (event.getAction() == MotionEvent.ACTION_DOWN) {
    rocketAnimation.start();
    return true;
  }
  return super.onTouchEvent(event);
}

对于那种oneshot的动画而言,动画执行结束后,再次直接调用调用start()方法,不会触发动画再次执行,而需要先调用stop(),再调用start()方法,才会再次出发动画的执行,如下面的代码所示:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            rocketAnimation.stop();
            rocketAnimation.start();
            return true;
        }
        return super.onTouchEvent(event);
    }

要注意的非常重要的一点是,不能在你的Activity的onCreate()方法中调用AnimationDrawable的start()方法,因为AnimationDrawable还没有完全被附接到window。如果你想要立即播放动画,而不需要交互,则你可以在你的Activity的onWindowFocusChanged()方法中调用它,这个方法将在Android使你的window获得focus时被调到。

更多关于XML语法,可用的tags和属性的信息,请参见Animation Resources

译自:

http://developer.android.com/guide/topics/graphics/view-animation.html,http://developer.android.com/guide/topics/graphics/drawable-animation.html

Done.

转载于:https://my.oschina.net/wolfcs/blog/330645

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值