补间动画(Tween)----/res/anim
1)原理
补间动画就是指开发者只需要指定动画开始,动画结束关键帧,而动画变化的中间帧由系统计算并补齐。对于补间动画而言,开发者无须逐一定义动画过程中的每一帧,只要定义动画开始,结束的关键帧,并指定动画的持续时间即可。持续时间计算出需要在中间补入多少帧。为了具体计算出在运行时补入多少帧,还需要借助于Interpolator属性。
Interpolator控制动画的变化速度。
2)如何定义res/anim目录
定义补间动画的xml资源文件以<set>元素为根
元素,该元素内可以指定如下4个元素:
alpha:设置透明度的改变和动画持续时间,其透明度可从0变化到1.
scale:设置图片进行缩放改变
translate:设置图片进行位移变换
rotate:设置图片进行旋转
对应的Java类AlphaAnimation,ScaleAnimation,
TranslateAnimation,RotateAnimation,
语法格式:
<set android:interpolator=""
xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true|false"
android:duration="持久时间">
<alpha android:fromAlpha="0.0--1.0"
android:toAlpha="0.0--1.0"
android:duration="持久时间"
android:repeatMode="reverse|restart"
android:repeatCount="次数|infinite"
android:startOffset="1000"/>
其中repeatMode设置重复的模式,reverse反转,方向改变
restart重新开始,方向不变
repeatCount重复的次数,动画将会执行该值+1次,
值为infinite表示无限循环
startOffset动画多次执行的间隔时间,如果只执行一次,
执行前会暂停这段时间,单位毫秒
<scale android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float"
android:duration="持久时间"
android:repeatMode="reverse|restart"
android:repeatCount="次数|infinite"/>
其中:
fromXScale,fromYScale 动画开始前X,Y的缩放,0.0为不显示,1.0为正常大小
toXScale,toYScale 动画最终缩放的倍数,1.0为正常大小,大于1.0放大
pivotX, pivotY 动画起始位置,属性为动画相对于物件的X坐标的开始位
置属性为动画相对于物件的Y坐标的开始位置
说明:以上两个属性值从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
startOffset, 动画多次执行的间隔时间,如果只执行一次,
执行前会暂停这段时间,单位毫秒
duration,一次动画效果消耗的时间,单位毫秒,值越小动画速度越快
<translate android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float"
android:duration="持久时间"
android:repeatMode="reverse|restart"
android:repeatCount="次数|infinite"/>
其中:fromXDelta,fromYDelta 起始时X,Y坐标,
toXDelta, toYDelta 动画结束时X,Y的坐标
以图片的当前位置为坐标原点。
<rotate android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float"
android:duration="持久时间"
android:repeatMode="reverse|restart"
android:repeatCount="次数|infinite"/>
其中:fromDegrees:动画开始的角度
toDegrees:动画结束的角度,正代表顺时针
privotX:相对于物件的X坐标开始位置进行旋转
privotY:相对于物件的Y坐标开始位置进行旋转
</set>
其中大量fromXxx,toXxx属性设置用于定义图片的
开始状态,结束状态。当进行缩放变换scale,旋转
rotate变换时,还需要指定pivotX,pivotY属性,
这两个属性用于指定变换的中心点,比如进行
旋转变换时,需要指定旋转点,缩放时指定缩放点。
另外<set><alpha><scale><translate><rotate>都
可以指定android:interpolator属性,该属性指定
动画的变化速度,可以实现匀速,正加速,负加速,
无规则变加速等。这些值在android系统的R.anim类
中包含了大量的常量,它们如:
@android:anim/linear_interpolator:匀速变换
accelerate_interpolator:加速变换
decelerate_interpolator:减速变换
cycle_interpolator:按正弦曲线变换
如果想要set元素下所有的变换效果使用相同的动画
速度,则可指定android:shareInterpolator="true"
3)在android代码中如何打开动画的步骤:
a)创建动画对象Animation:
Animation anim = AnimationUtils.loadAnimation
(Context,动画资源int(R.anim.scale_xml));
b)可以设置动画结束后保留什么状态
anim.setFillBefore(true);开始状态
anim.setFillAfter(true);结束状态
c)开始动画
组件(View).startAnimation(anim);
d)给Animation添加事件监听(选择性的)
anim.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
//跳转到另外一个Activity(主Activity)
}
});
详情:
ii)alpha透明度效果
<alpha android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="3000"/>
ii)rotate旋转效果
<rotate android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="300"
android:toDegrees="-30"
android:pivotX="50%"
android:pivotY="50%"
android:duration="10000"/>
ii)scale缩放效果
<scale android:interpolator="@android:anim/decelerate_interpolator"
android:fromXScale="0.0"
android:toXScale="1.5"
android:fromYScale="0.0"
android:toYScale="1.5"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="1000"
android:repeatCount="5"
android:repeatMode="restart"
android:duration="10000"/>
ii)translate移动效果
<translate android:fromXDelta="200"
android:toXDelta="0"
android:fromYDelta="200"
android:toYDelta="0"
android:duration="10000"/>
ii)可以多种动画结合使用
比如说透明,旋转,缩放
补充:加速器
AccelerateInterpolator:加速,开始时慢中间加速
DecelerateInterpolator:减速,开始时快然后减速
AccelerateDecelerateInterolator:先加速后减速,开始结束时慢,中间加速
AnticipateInterpolator:反向,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator:反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator:跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator:循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles* Math.PI* input)
LinearInterpolator:线性,线性均匀改变
OvershottInterpolator:超越,最后超出目的值然后缓慢改变到目的值
4)代码编写:
先看效果图吧:
activity_main:
<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"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始动画"
android:onClick="mystart"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/img"
android:src="@drawable/brownmonsters19"
android:layout_centerInParent="true"/>
</RelativeLayout>
在res文件下新建了anim文件,在anim文件写了my_scale,my_set,my_translate,my_rotate,my_alpha
my_scale:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 缩放动画 -->
<scale android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="2.0"
android:toYScale="2.0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="5"
android:repeatMode="reverse"
android:duration="1000"/>
</set>
my_set:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.01"
android:toYScale="0.01"
android:pivotX="50%"
android:pivotY="50%"
android:duration="3000"/>
<alpha android:fromAlpha="1"
android:toAlpha="0.05"
android:duration="3000"/>
<rotate android:fromDegrees="0"
android:toDegrees="1800"
android:pivotX="50%"
android:pivotY="50%"
android:duration="3000"/>
</set>
my_translate:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 位置动画 -->
<translate android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="100"
android:duration="1000"
android:repeatCount="5"
android:repeatMode="reverse"
android:interpolator="@android:anim/bounce_interpolator"/>
</set>
my_rotate:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 旋转动画 -->
<rotate android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
android:repeatCount="3"
android:repeatMode="reverse"/>
</set>
my_alpha:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 透明度动画 -->
<alpha android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="5000"
android:repeatCount="2"
android:repeatMode="reverse"
android:startOffset="1000"/>
</set>
MainActivity:
public void mystart(View view) {
// TODO Auto-generated method stub
//播放补间动画
Animation am=AnimationUtils.loadAnimation(this,
//R.anim.my_alpha);
//R.anim.my_scale);
//R.anim.my_translate);
//R.anim.my_rotate);
R.anim.my_set);
//动画停留在结束的地方
am.setFillAfter(true);
iv.startAnimation(am);
//给动画加监听器
am.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this,OtherAcivity.class));
finish();
}
});
}