View动画
你可以使用view动画系统执行Views的补间动画。补间动画通过诸如起始点,终止点,大小,旋转,和一个动画其他通用的aspects等信息来计算动画。
一个补间动画可以在一个View对象的内容上执行一系列简单的变换(位置,大小,旋转,透明度)。因此,如果你有一个TextView对象,你可以移动,旋转,放大,或收缩文本。如果你有一个背景图片,则背景图片将随着文字而转换。animation包提供了用于一个补间动画的所有的类。
一系列的动画指令定义了补间动画,由XML或Android代码定义。至于定义一个layout,则建议用一个XML文件来定义,因为它相对于硬编码动画更可读,可复用,可交换。在下面的例子中,我们使用XML。(要学习更多在你的应用代码中定义一个动画而不是在XML中的方法,请参考AnimationSet类及其他的Animation子类。)
动画指令定义了你想要执行的变换,何时执行变换,及它们应当执行多长时间。变换可以是串行的或并行的——比如,你可以使得一个TextView的内容自左向右移动,然后旋转180度,或你可以使文字的移动和旋转并行执行。每种变换需要一系列特定于变换的参数(大小变换的起始大小和结束大小,旋转的起始角度和结束角度,等等),及一系列的通用参数(比如,其实时间和持续时间)。要使多个变换并发执行,则提供给它们相同的起始时间;要使它们串行执行,则计算起始时间时加上前一个变换的持续时间。
动画XML文件应当放在你的Android工程的res/anim/目录下。文件必须有一个单独的根元素:这可能是一个单独的
下面来自于一个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 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。
译自:
Done.