Android动画译文(下)

来源:互联网 发布:黑白网络黑客教程 编辑:程序博客网 时间:2024/05/22 00:16

声明:以下内容翻译于Android官网 Animation and Graphics章节。如果有表述不合理的地方,欢迎指正。

视图动画

我们可以使用视图动画系统来对视图执行补间动画。补间动画利用起点、终点、尺寸、旋转角度等信息来计算动画。

补间动画可以对视图执行一系列简单的变化(位置、角度、尺寸、透明度)。例如,对一个TextView我们可以对其移动、旋转、抖动文字。如果有背景图片,背景会跟着文字一起变化。

可以通过XML文件或者Android代码来定义一系列补间动画的指令。就像在定义布局时,一般推荐XML文件,因为它可读性、重用性、交换性更好。这些指令定义了你想要什么样的变化,变化什么时候发生以及变化的时长。

这些变化可以是有序的或者同时发生。例如,我们可以使一个TextView的内容从左移到右,然后旋转180度或者我们可以同时执行上面两个动画。每个变化都需要指定 一些特定的参数(开始尺寸、结束尺寸,开始角度、结束角度等)和一些通用的参数(开始时间和时长)。如果想让几个变化同时发生,就给他们设置相同的开始时间,如果想让几个变化有序发生,就将开始时间和时间间隔相加。

动画的XML文件放在Android项目的res/anim/目录下。文件只能有一个根标签,可以是<alpha>, <scale>, <translate>, <rotate>,插值器元素或者<set>标签中的一个。<set> 标签可以包裹一组其他元素,当然也可以包裹另一个<set>标签。默认情况,所有的动画指令同时执行。如果想让他们有序执行,必须指定startOffset 属性。

下面是ApiDemo中的一个例子,使一个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>
一些像pivotX这样的属性既可以指定相对自身也可以指定相对父容器。所以在使用时确定使用正确的格式(“50”指相对父容器“50%”,“50%”指相对自身“50%”)我们也可以指定指定Interpolator来决定变化随时间的关系。Android提供了一些Interpolator子类,定义了不同的速度曲线。在res/anim/目录下定义好动画后,按照下面的例子,就可以引用这个动画并将其使用到一个TextView上:
TextView textView = (TextView) findViewById(R.id.spaceshipImage);Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);textView.startAnimation(hyperspaceJumpAnimation);
动画效果如下:

除了调用startAnimation()开始动画外,我们还能通过Animation.setStartTime()方法对动画指定开始时间,然后通过View.setAnimation()应用动画。

注意:不管动画如何移动或改变尺寸,View的边界不会根据动画进行自动调整。不过可以绘制超出视图边界而不会被切割,但是如果超出了父容器的边界,视图就会被切割。如下图,蓝色区域为父容器区域。

图片动画

图片动画是指从一系列图片资源中一张张加载图片产生的动画。这是一种很传统的动画,在一个场景中,有一系列不同的图片,按一定顺序播放,就像一卷胶卷。AnimationDrawable是图片动画的主要类。

当我们需要在代码中定义动画的帧时,我们使用AnimationDrawable类。它只需要在xml文件中列出组成动画的帧就可以了。这种动画类型的xml文件位于res/drawable目录下。

xml文件由一个<animation-list>根标签和一系列<item> 子标签组成。每一个<item>定义一帧由一个图片资源和帧时长组成。下面是一个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>

这个动画只有三帧。android:oneshot 属性设置为true意味着,动画只执行一个周期然后停在最后一帧。如果设置为false,动画会循环执行。将以上xml保存成rocket_thrust.xml文件然后放置于res/drawable/目录下,他就可以作为背景资源添加到View上,然后被调用。下面这个例子,动画被添加到ImageView上,然后点击屏幕后执行。

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);}

要注意的是,start()方法不能再当前Activity的onCreate()方法中调用。因为此时,AnimationDrawable还没有被加载到窗体内。如果想要立刻播放动画,而不是通过交互,那么我们可以在当前Activity的onWindowFocusChanged()方法中调用start()方法,之后该方法会再当前窗体获得焦点后执行。

0 0
原创粉丝点击