Android 补间动画(Tween)之一 Tween动画与Interpolator

来源:互联网 发布:淘宝详情页关联宝贝 编辑:程序博客网 时间:2024/06/04 22:18

对于补间动画而言,我们无须"逐一"定义动画过程中的每一帧,只要定义动画开始,结束的关键帧,并制定动画的持续时间即可.

补间动画所定义的开始帧,结束帧其实只是一些简单的变化,比如图形大小的缩放,旋转角度的改变等.android使用Animation代表抽象的动画类,它包括如下几个子类.

> AlphaAnimation: 透明度改变的动画.创建该动画时要指定动画开始时的透明度,结束时的透明度和动画持续时间.其中透明度可从0变化到1.

> ScaleAnimation: 大小缩放的动画.创建该动画时要指定动画开始时的缩放比(以X,Y轴的缩放参数来表示),结束时动画的缩放比(以X,Y轴的缩放参数来表示),并指定动画持续时间.由于缩放时以不同点为中心时缩放效果并不相同,因此指定缩放动画时还要通过pivotX,pivotY来制定"缩放中心"的坐标.

> TranslateAnimation: 位移变化的动画,创建该动画时只要指定动画开始时的位置(以X,Y坐标来表示),结束时的位置(以X,Y坐标来表示),并指定动画持续时间即可.

> RotateAnimation: 旋转动画,创建该动画时只要指定动画开始时的旋转角度,结束时的旋转角度,并指定动画持续时间即可.由于旋转时以不同点为中心时旋转效果并不相同,因此指定旋转动画时还要通过pivotX,pivotY来制定"旋转轴心"的坐标.

一旦为补间动画制定了三个必要信息,Android就会根据动画的开始帧,结束帧,动画持续时间计算出需要在中间"补入"多少帧,具体在动画运行的那些时刻补入帧,需要借助于Interpolator.

Interpolator根据特定算法计算出整个动画所需要动态插入帧的密度和位置,简单地说,Interpolator负责控制动画的变化速度,这就使得基本的动画效果(Alpha,Scale,Translate,Rotate)能以匀速变化,加速,减速,抛物线速度等各种速度变化.

Interpolator是一个接口,它定义了所有Interpolator都需要实现的方法:float getInterpolation(float input),这个方法就可以完全通过实现Interpolator来控制动画的变化速度.

Android为Interpolator提供了如下几个实现类,分别用于实现不同动画变化速度.

> LinearInterpolator: 动画以均匀的速度改变.

> AccelerateInterpolator: 在动画开始的地方改变速度较慢,然后开始加速.

> AccelerateDecelerateInterpolator: 在动画开始,结束的地方改变速度较慢,在中间的时候加速.

> CycleInterpolator: 动画循环播放特定的次数,变化速度按正弦曲线改变.

> DecelerateInterpolator: 在动画开始的地方改变速度较快,然后开始减速.

为了在动画资源文件中指定补间动画所使用的Interpolator,定义补间动画的<set.../>元素支持一个android:interpolator属性,该属性的属性值可指定为Android默认支持的Interpolator.例如:

> @android:anim/linear_interpolator

> @android:anim/accelerate_interpolator

> @android:anim/accelerate_decelerate_interpolator

......

上面的属性很有规律,就是把系统提供的Interpolator实现类的类名的驼峰写法改为下划线写法即可.

一旦在程序中通过AnimationUtils得到代表补间动画的Animation之后,接下来就可调用View的startAnimation(Animation anim)方法开始对该View之行动画了.

下面的就是第一个补间动画例子:

1.tween_anim.xml补间动画资源.

<?xml version="1.0" encoding="utf-8"?><!-- 指定动画匀速改变 --><set xmlns:android="http://schemas.android.com/apk/res/android"    android:interpolator="@android:anim/linear_interpolator" >    <!-- 定义缩放变换 -->    <scale        android:duration="3000"        android:fillAfter="true"        android:fromXScale="1.0"        android:fromYScale="1.0"        android:pivotX="50%"        android:pivotY="50%"        android:toXScale="0.01"        android:toYScale="0.01" />    <!-- 定义透明变换 -->    <alpha        android:duration="3000"        android:fromAlpha="1"        android:toAlpha="0.05" />    <!-- 定义旋转动画 -->    <rotate        android:duration="3000"        android:fromDegrees="0"        android:pivotX="50%"        android:pivotY="50%"        android:toDegrees="1800" /></set>
2.activity.java文件

package com.example.animationdemo;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.Button;import android.widget.ImageView;/** * 补间动画中的缩放动画,换转动画,透明度动画效果 * @author Administrator * */public class TweenAnimActivity extends Activity {private ImageView mImageView;private Button mBtn;private Animation mAnimation,mReverseAnimation;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_tween_anim);mImageView = (ImageView) findViewById(R.id.tween_image);mBtn = (Button) findViewById(R.id.tween_btn);//加载第一份动画资源mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim);//设置动画结束后保持在结束状态mAnimation.setFillAfter(true);//加载第二份动画资源mReverseAnimation = AnimationUtils.loadAnimation(this, R.anim.reverse);//设置动画结束后保持在结束状态mReverseAnimation.setFillAfter(true);final Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == 0x123) {mImageView.startAnimation(mReverseAnimation);}}};mBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {mImageView.startAnimation(mAnimation);//设置3.5秒后启动第二个动画new Timer().schedule(new TimerTask() {@Overridepublic void run() {handler.sendEmptyMessage(0x123);}}, 3500);}});}}
3.activity.xml布局文件

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">        <ImageView         android:id="@+id/tween_image"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true"        android:background="@drawable/ic_launcher"/>        <Button         android:id="@+id/tween_btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="播放补间动画"/>    </RelativeLayout>

下面的为第二个例子,

逐帧动画与补间动画中的平移动画

1.逐帧动画资源

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="false" >    <item        android:drawable="@drawable/diaozui0"        android:duration="120"/>    <item        android:drawable="@drawable/diaozui1"        android:duration="120"/>    <item        android:drawable="@drawable/diaozui2"        android:duration="120"/>    <item        android:drawable="@drawable/diaozui3"        android:duration="120"/>    <item        android:drawable="@drawable/diaozui4"        android:duration="120"/>    <item        android:drawable="@drawable/diaozui5"        android:duration="120"/>    <item        android:drawable="@drawable/diaozui6"        android:duration="120"/>    <item        android:drawable="@drawable/diaozui7"        android:duration="120"/></animation-list>

2.补间动画资源

<?xml version="1.0" encoding="utf-8"?><!-- 指定动画匀速改变 --><set xmlns:android="http://schemas.android.com/apk/res/android"    android:interpolator="@android:anim/linear_interpolator"    android:startOffset="3000" >    <!-- 指定缩放动画 -->    <scale        android:duration="3000"        android:fillAfter="true"        android:fromXScale="0.01"        android:fromYScale="0.01"        android:pivotX="50%"        android:pivotY="50%"        android:toXScale="1.0"        android:toYScale="1.0" />    <!-- 指定透明度动画 -->    <alpha        android:duration="3000"        android:fromAlpha="0.05"        android:toAlpha="1.0" />    <!-- 指定旋转动画 -->    <rotate        android:duration="3000"        android:fromDegrees="1800"        android:pivotX="50%"        android:pivotY="50%"        android:toDegrees="0" /></set>
3.activity.java文件

package com.example.animationdemo;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.graphics.drawable.AnimationDrawable;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.view.animation.TranslateAnimation;import android.widget.ImageView;/*** *逐帧动画,与补间动画中的平移动画联合使用 * @author Administrator * */public class ButterflyActivity extends Activity {private ImageView mImageView;private AnimationDrawable mAnimationDrawable;/**记录组件的当前X坐标*/private int curX = 0;/**记录组件的当前Y坐标*/private int curY = 0;/**记录组件的下一个位置X坐标*/private int nextX = 0;/**记录组件的下一个位置Y坐标*/private int nextY = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_butterfly);//获取组件mImageView = (ImageView) findViewById(R.id.butterfly_imageview);final Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if(msg.what == 0x123){//组件在横向上面一直向右移动if(curX >= 1080){curX = nextX = 0;}else{nextX += 5;}//纵向上面随机上下移动nextY = (int) (Math.random() * 10 -5);//设置组件的位移改变TranslateAnimation translateAnimation = new TranslateAnimation(curX, nextX, curY, nextY);curX = nextX;curY = nextY;translateAnimation.setDuration(200);//开始位移动画mImageView.startAnimation(translateAnimation);}}};//获取逐帧动画对象mAnimationDrawable = (AnimationDrawable) mImageView.getBackground();mImageView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//开始播放逐帧动画mAnimationDrawable.start();//通过定时器控制没过0.2秒运行一次TranslateAnimation动画new Timer().schedule(new TimerTask() {@Overridepublic void run() {handler.sendEmptyMessage(0x123);}}, 0, 200);}});}}

4.activity布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <ImageView 
        android:id="@+id/butterfly_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@anim/butterfly"/>
</RelativeLayout>

呵呵,上面的两个例子,供大家参考哦.....




0 0