补间动画(Tween Animation)
补间动画与逐帧动画在本质上是不同的,逐帧动画通过连续播放图片来模拟动画的效果,而补间动画则是通过在两个关键帧之间补充渐变的动画效果来实现的。补间动画的优点是可以节省空间。
目前Android应用框架支持的补间动画效果有以下5种。具体实现在android.view.animation类库中。
效果如下:
AlphaAnimation:透明度(alpha)渐变效果,对应<alpha/>标签。
TranslateAnimation:位移渐变,需要指定移动点的开始和结束坐标,对应<translate/>标签。
ScaleAnimation:缩放渐变,可以指定缩放的参考点,对应<scale/>标签。
RotateAnimation:旋转渐变,可以指定旋转的参考点,对应<rotate/>标签。
AnimationSet:组合渐变,支持组合多种渐变效果,对应<set/>标签。
补间动画的效果同样可以使用XML语言来定义,这些动画模板文件通常会被放在Android项目的res/anim/目录下。
下面是具体实现源码:
MainActivity.java封装实现的方法:
- package com.example.lesson19_tween;
- import com.example.lesson19_tween.R;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.View;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.view.animation.ScaleAnimation;
- import android.view.animation.TranslateAnimation;
- import android.widget.ImageView;
- public class MainActivity extends Activity {
- private ImageView imageView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- imageView = (ImageView) findViewById(R.id.imageView1);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- // 透明动画
- public void alphaImpl(View v) {
- Animation animation = AnimationUtils.loadAnimation(this,
- R.anim.alpha_demo);
- imageView.startAnimation(animation);
- }
- // 旋转动画
- public void rotateImpl(View v) {
- Animation animation = AnimationUtils.loadAnimation(this,
- R.anim.rotate_demo);
- imageView.startAnimation(animation);
- }
- // 缩放动画
- public void scaleImpl(View v) {
- Animation animation = AnimationUtils.loadAnimation(this,
- R.anim.scale_demo);
- imageView.startAnimation(animation);
- }
- // 移动效果
- public void translateImpl(View v) {
- // XML文件
- Animation animation = AnimationUtils.loadAnimation(this,
- R.anim.translate_demo);
- animation.setRepeatCount(Animation.INFINITE);//循环显示
- imageView.startAnimation(animation);
- /*
- * 第一种 imageView.setAnimation(animation); animation.start();
- */
- // 第二种
- // Java代码
- /*
- * TranslateAnimation translateAnimation = new TranslateAnimation(0,
- * 200, 0, 0); translateAnimation.setDuration(2000);
- * imageView.startAnimation(translateAnimation);
- */
- }
- // 综合实现set_demo.xml中的动画
- public void setAll(View v) {
- Animation animation = AnimationUtils.loadAnimation(this,
- R.anim.set_demo);
- imageView.startAnimation(animation);
- }
- }
alpha_demo.xml
- <alpha xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_decelerate_interpolator"
- android:fromAlpha="1.0"
- android:toAlpha="0.1"
- android:duration="2000"/>
- <!--
- fromAlpha :起始透明度
- toAlpha:结束透明度
- 1.0表示完全不透明
- 0.0表示完全透明
- -->
rotate_demo.xml
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_decelerate_interpolator"
- android:fromDegrees="0"
- android:toDegrees="360"
- android:duration="1000"
- android:repeatCount="1"
- android:repeatMode="reverse"/>
- <!--
- fromDegrees:表示旋转的起始角度
- toDegrees:表示旋转的结束角度
- repeatCount:旋转的次数 默认值是0 代表旋转1次 如果值是repeatCount=4 旋转5次,值为-1或者infinite时,表示补间动画永不停止
- repeatMode 设置重复的模式。默认是restart。当repeatCount的值大于0或者为infinite时才有效。
- repeatCount=-1 或者infinite 循环了
- 还可以设成reverse,表示偶数次显示动画时会做与动画文件定义的方向相反的方向动行。
- -->
scale_demo.xml
- <scale xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator"
- android:fromXScale="0.2"
- android:toXScale="1.5"
- android:fromYScale="0.2"
- android:toYScale="1.5"
- android:pivotX="50%"
- android:pivotY="50%"
- android:duration="2000"/>
- <!--
- fromXScale:表示沿着x轴缩放的起始比例
- toXScale:表示沿着x轴缩放的结束比例
- fromYScale:表示沿着y轴缩放的起始比例
- toYScale:表示沿着y轴缩放的结束比例
- 图片中心点:
- android:pivotX="50%"
- android:pivotY="50%"
- -->
translate_demo.xml
- <translate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_decelerate_interpolator"
- android:fromXDelta="0"
- android:toXDelta="320"
- android:fromYDelta="0"
- android:toYDelta="0"
- android:duration="2000"/>
- <!--
- android:interpolator 动画的渲染器
- 1、accelerate_interpolator(动画加速器) 使动画在开始的时候 最慢,然后逐渐加速
- 2、decelerate_interpolator(动画减速器)使动画在开始的时候 最快,然后逐渐减速
- 3、accelerate_decelerate_interpolator(动画加速减速器)
- 中间位置分层: 使动画在开始的时候 最慢,然后逐渐加速
- 使动画在开始的时候 最快,然后逐渐减速 结束的位置最慢
- fromXDelta 动画起始位置的横坐标
- toXDelta 动画起结束位置的横坐标
- fromYDelta 动画起始位置的纵坐标
- toYDelta 动画结束位置的纵坐标
- duration 动画的持续时间
- -->
set_demo.xml
- <set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:shareInterpolator="true" >
- <scale
- android:duration="2000"
- android:fromXScale="0.2"
- android:fromYScale="0.2"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toXScale="1.5"
- android:toYScale="1.5" />
- <rotate
- android:duration="1000"
- android:fromDegrees="0"
- android:repeatCount="1"
- android:repeatMode="reverse"
- android:toDegrees="360" />
- <translate
- android:duration="2000"
- android:fromXDelta="0"
- android:fromYDelta="0"
- android:toXDelta="320"
- android:toYDelta="0" />
- <alpha
- android:duration="2000"
- android:fromAlpha="1.0"
- android:toAlpha="0.1" />
- </set>
布局文件:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context=".MainActivity" >
- <Button
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:layout_marginLeft="23dp"
- android:layout_marginTop="15dp"
- android:onClick="translateImpl"
- android:text="@string/text_translate" />
- <Button
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/button1"
- android:layout_marginLeft="21dp"
- android:onClick="rotateImpl"
- android:layout_toRightOf="@+id/imageView1"
- android:text="@string/text_rotate" />
- <Button
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignRight="@+id/button1"
- android:layout_below="@+id/button1"
- android:layout_marginTop="32dp"
- android:onClick="scaleImpl"
- android:text="@string/text_scale" />
- <Button
- android:id="@+id/button4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/button3"
- android:layout_alignBottom="@+id/button3"
- android:layout_alignLeft="@+id/button2"
- android:onClick="alphaImpl"
- android:text="@string/text_alpha" />
- <Button
- android:id="@+id/button5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/button3"
- android:layout_centerHorizontal="true"
- android:onClick="setAll"
- android:text="@string/text_set" />
- <ImageView
- android:id="@+id/imageView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/button5"
- android:layout_marginTop="48dp"
- android:layout_toRightOf="@+id/button3"
- android:src="@drawable/ic_launcher" />
- </RelativeLayout>
在实际项目中,我们经常使用补间动画,原因是补间动画使用起来比较方便,功能也比逐帧动画强大不少,而且还可以很方便地进行动画叠加,实现更加复杂的效果。实际上,set_demo.xml中的<set/>标签对应的就是AnimationSet类,即“动画集合”的概念,支持加入多种动画效果,如渐变动画(alpha)、大小动画(scale),线性动画(translate)等。另外,在Android系统中,所有与动画相关的类都归类在android.view.animation包之下,大家可以参考SDK文档进行进一步学习。
至此,我们已经初步了解了如何在Android系统中使用各种动画效果,包括逐帧动画和补间动画。显而易见的是,在Android平台之上,开发者们可以很方便地使用各种动画效果来为应用产品增色。