您的位置:首页 > 移动开发 > Android开发

Android动画译文(下)

2016-07-19 16:48 405 查看
声明:以下内容翻译于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_thru
9f10
st1" 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()方法,之后该方法会再当前窗体获得焦点后执行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 动画