动画简介
(一)、概要:
3.0以前,android支持两种动画模式,补间动画(tween animation),帧动画(frame animation),在android3.0中又引入了一个新的动画系统:属性动画(property animation)。
这三种动画模式在SDK中被称为view animation,drawable animation,property animation。
(二)、动画资源分类:
属性动画:Property Animation
帧动画:Frame Animation (Drawable Animation)
补间动画:Tween Animation (View Animation)
透明度补间动画
缩放补间动画
旋转补间动画
移动补间动画
(三)、补间动画
View Animation就是一系列View形状的变换,如大小的缩放、透明度的改变、水平位置的改变、旋转位置改变,动画的定义既可以用java代码定义也可以用XML定义。建议用XML定义。
用XML定义的动画放在/res/anim/文件夹内,XML文件的根元素为<set> , 二级节点可为<alpha>,<scale>,<translate>,<rotate>。
AlphaAnimation:透明度(alpha)渐变效果,对应<alpha/>标签。
TranslateAnimation:位移渐变,需要指定移动点的开始和结束坐标,对应<translate/>标签。
ScaleAnimation:缩放渐变,可以指定缩放的参考点,对应<scale/>标签。
RotateAnimation:旋转渐变,可以指定旋转的参考点,对应<rotate/>标签。
AnimationSet:组合渐变,支持组合多种渐变效果,对应<set/>标签。
动画插入器
AccelerateInterpolator 加速,开始时慢中间加速
DecelerateInterpolator 减速,开始时快然后减速
AccelerateDecelerateInterpolator 先加速后减速,开始结束时慢,中间加速
AnticipateInterpolator 反向,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles*Math.PI* input)
LinearInterpolator 线性,线性均匀改变
OvershottInterpolator 超越,最后超出目的值然后缓慢改变到目的值
(五)XML方式实现补间动画
移动
旋转
附上源码: 源码
(一)、概要:
3.0以前,android支持两种动画模式,补间动画(tween animation),帧动画(frame animation),在android3.0中又引入了一个新的动画系统:属性动画(property animation)。
这三种动画模式在SDK中被称为view animation,drawable animation,property animation。
(二)、动画资源分类:
属性动画:Property Animation
帧动画:Frame Animation (Drawable Animation)
补间动画:Tween Animation (View Animation)
透明度补间动画
缩放补间动画
旋转补间动画
移动补间动画
(三)、补间动画
View Animation就是一系列View形状的变换,如大小的缩放、透明度的改变、水平位置的改变、旋转位置改变,动画的定义既可以用java代码定义也可以用XML定义。建议用XML定义。
用XML定义的动画放在/res/anim/文件夹内,XML文件的根元素为<set> , 二级节点可为<alpha>,<scale>,<translate>,<rotate>。
AlphaAnimation:透明度(alpha)渐变效果,对应<alpha/>标签。
TranslateAnimation:位移渐变,需要指定移动点的开始和结束坐标,对应<translate/>标签。
ScaleAnimation:缩放渐变,可以指定缩放的参考点,对应<scale/>标签。
RotateAnimation:旋转渐变,可以指定旋转的参考点,对应<rotate/>标签。
AnimationSet:组合渐变,支持组合多种渐变效果,对应<set/>标签。
动画插入器
AccelerateInterpolator 加速,开始时慢中间加速
DecelerateInterpolator 减速,开始时快然后减速
AccelerateDecelerateInterpolator 先加速后减速,开始结束时慢,中间加速
AnticipateInterpolator 反向,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles*Math.PI* input)
LinearInterpolator 线性,线性均匀改变
OvershottInterpolator 超越,最后超出目的值然后缓慢改变到目的值
(四)JAVA代码实现补间动画
每个都做了注释,使用和参数的填写
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//点击TAG
private final int ANIM_TRANSLATE = 0,ANIM_ROATE = 1,ANIM_SCALE = 2,ANIM_ALPH = 3,ANIM_ALL = 4;
private Button button_translate,button_roate,button_scale,button_alpha,button_all;
private ImageView myImage;
private Animation animation;
/**
* 绑定
*/
//private Animation animation;
private void initView(){
button_translate = (Button) findViewById(R.id.button_translate);
button_roate = (Button) findViewById(R.id.button_roate);
button_scale = (Button) findViewById(R.id.button_scale);
button_alpha = (Button) findViewById(R.id.button_alpha);
button_all = (Button) findViewById(R.id.button_all);
button_translate.setTag(ANIM_TRANSLATE);
button_roate.setTag(ANIM_ROATE);
button_scale.setTag(ANIM_SCALE);
button_alpha.setTag(ANIM_ALPH);
button_all.setTag(ANIM_ALL);
myImage = (ImageView) findViewById(R.id.myImage);
}
/**
* 点击事件
*/
private void initCtrl(){
button_translate.setOnClickListener(this);
button_alpha.setOnClickListener(this);
button_roate.setOnClickListener(this);
button_scale.setOnClickListener(this);
button_all.setOnClickListener(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initCtrl();
}
/**
* 动画插入器
AccelerateInterpolator 加速,开始时慢中间加速
DecelerateInterpolator 减速,开始时快然后减速
AccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速
AnticipateInterpolator 反向,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles*Math.PI* input)
LinearInterpolator 线性,线性均匀改变
OvershottInterpolator 超越,最后超出目的值然后缓慢改变到目的值
*/
private void TrandlateAnim(){
// 起始坐标x,y和终点坐标x,y
animation = new TranslateAnimation(0,200,0,200);
//3秒完成动画
animation.setDuration(2000);
//如果fillAfter的值为真的话,动画结束后,控件停留在执行后的状态
animation.setFillAfter(false);
animation.setInterpolator(new AccelerateInterpolator());
//启动动画
myImage.startAnimation(animation);
//动画的监听
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.e("ceshi", "移动动画开始");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.e("ceshi", "移动动画结束");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.e("ceshi", "移动动画重复");
}
});
}
/**
* 旋转
*/
private void RoateAnim(){
//旋转起始度数,旋转的点
animation = new RotateAnimation(0, 30, myImage.getWidth(), myImage.getHeight());
animation.setInterpolator(new DecelerateInterpolator());
animation.setDuration(2000);
animation.setFillAfter(false);
myImage.startAnimation(animation);
}
private void AlphAnim(){
//构造方法的两个参数是指,开始时候的透明度和结束时候的透明度
animation = new AlphaAnimation(1.0f, 0.7f);
animation.setInterpolator(new AccelerateDecelerateInterpolator());
animation.setDuration(2000);
animation.setFillAfter(false);
myImage.startAnimation(animation);
}
private void ScaleAnim(){
/*float fromX 动画起始时 X坐标上的伸缩尺寸
float toX 动画结束时 X坐标上的伸缩尺寸
float fromY 动画起始时Y坐标上的伸缩尺寸
float toY 动画结束时Y坐标上的伸缩尺寸
int pivotXType 动画在X轴相对于物件位置类型
float pivotXValue 动画相对于物件的X坐标的开始位置
int pivotYType 动画在Y轴相对于物件位置类型
float pivotYValue 动画相对于物件的Y坐标的开始位置 */
animation = new ScaleAnimation(1.0f, 0f, 1.0f, 0f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setInterpolator(new AnticipateInterpolator());
animation.setDuration(2000);
animation.setFillAfter(false);
myImage.startAnimation(animation);
}
/**
* 动画集合
*/
private void AllAnim(){
// 是否多个animation使用同一个动画插入器
AnimationSet animationSet = new AnimationSet(false);
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f);
scaleAnimation.setDuration(2000);
animationSet.addAnimation(scaleAnimation);
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
alphaAnimation.setDuration(2000);
animationSet.addAnimation(alphaAnimation);
TranslateAnimation translateAnimation = new TranslateAnimation(0, 200, 0, 200);
alphaAnimation.setDuration(2000);
animationSet.addAnimation(translateAnimation);
RotateAnimation rotateAnimation = new RotateAnimation(0, 30, myImage.getWidth(), myImage.getHeight());
animationSet.addAnimation(rotateAnimation);
myImage.startAnimation(animationSet);
}
@Override
public void onClick(View view) {
switch ((Integer)view.getTag()){
case ANIM_TRANSLATE:
TrandlateAnim();
break;
case ANIM_ALPH:
AlphAnim();
break;
case ANIM_ROATE:
RoateAnim();
break;
case ANIM_SCALE:
ScaleAnim();
break;
case ANIM_ALL:
AllAnim();
break;
}
}
}
(五)XML方式实现补间动画
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//点击事件
private final int ANIM_TRANSLATE = 0,ANIM_ROATE = 1,ANIM_SCALE = 2,ANIM_ALPH = 3,ANIM_ALL = 4;
private Button button_translate,button_roate,button_scale,button_alpha,button_all;
private ImageView myImage;
private Animation animation;
/**
* 初始化按钮
*/
//private Animation animation;
private void initView(){
button_translate = (Button) findViewById(R.id.button_translate);
button_roate = (Button) findViewById(R.id.button_roate);
button_scale = (Button) findViewById(R.id.button_scale);
button_alpha = (Button) findViewById(R.id.button_alpha);
button_all = (Button) findViewById(R.id.button_all);
button_translate.setTag(ANIM_TRANSLATE);
button_roate.setTag(ANIM_ROATE);
button_scale.setTag(ANIM_SCALE);
button_alpha.setTag(ANIM_ALPH);
button_all.setTag(ANIM_ALL);
myImage = (ImageView) findViewById(R.id.myImage);
}
/**
* 点击事件
*/
private void initCtrl(){
button_translate.setOnClickListener(this);
button_alpha.setOnClickListener(this);
button_roate.setOnClickListener(this);
button_scale.setOnClickListener(this);
button_all.setOnClickListener(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initCtrl();
}
/**
* 移动
*/
private void TrandlateAnim(){
animation = AnimationUtils.loadAnimation(this,
R.anim.translate);
myImage.startAnimation(animation);
}
/**
* 透明度
*/
private void AlphAnim(){
animation = AnimationUtils.loadAnimation(this,
R.anim.alph);
myImage.startAnimation(animation);
}
/**
* 旋转
*/
private void RoateAnim(){
animation = AnimationUtils.loadAnimation(this,
R.anim.rotate);
myImage.startAnimation(animation);
}
/**
* 缩放
*/
private void ScaleAnim(){
animation = AnimationUtils.loadAnimation(this,
R.anim.scale);
myImage.startAnimation(animation);
}
/**
* 组合动画
*/
private void AllAnim(){
animation = AnimationUtils.loadAnimation(this,
R.anim.set);
myImage.startAnimation(animation);
}
@Override
public void onClick(View view) {
switch ((Integer)view.getTag()){
case ANIM_TRANSLATE:
TrandlateAnim();
break;
case ANIM_ALPH:
AlphAnim();
break;
case ANIM_ROATE:
RoateAnim();
break;
case ANIM_SCALE:
ScaleAnim();
break;
case ANIM_ALL:
AllAnim();
break;
}
}
}
移动
<!--
android:interpolator 动画的渲染器
1、accelerate_interpolator(动画加速器) 使动画在开始的时候 最慢,然后逐渐加速
2、decelerate_interpolator(动画减速器)使动画在开始的时候 最快,然后逐渐减速
3、accelerate_decelerate_interpolator(动画加速减速器)
中间位置分层: 使动画在开始的时候 最慢,然后逐渐加速
使动画在开始的时候 最快,然后逐渐减速 结束的位置最慢。。。
fromXDelta 动画起始位置的横坐标
toXDelta 动画起结束位置的横坐标
fromYDelta 动画起始位置的纵坐标
toYDelta 动画结束位置的纵坐标
duration 动画的持续时间
-->
<translate
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXDelta="0"
android:toXDelta="100"
android:fromYDelta="0"
android:fillAfter="true"
android:toYDelta="100"
android:duration="2000"
xmlns:android="http://schemas.android.com/apk/res/android" />
缩放
<!--
fromXScale:表示沿着x轴缩放的起始比例
toXScale:表示沿着x轴缩放的结束比例
fromYScale:表示沿着y轴缩放的起始比例
toYScale:表示沿着y轴缩放的结束比例
图片中心点:
android:pivotX="50%"
android:pivotY="50%"
-->
<scale
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"
xmlns:android="http://schemas.android.com/apk/res/android" />
旋转
<!--
fromDegrees:表示旋转的起始角度
toDegrees:表示旋转的结束角度
repeatCount:旋转的次数 默认值是0 代表旋转1次 如果值是repeatCount=4 旋转5次,值为-1或者infinite时,表示补间动画永不停止
repeatMode 设置重复的模式。默认是restart。当repeatCount的值大于0或者为infinite时才有效。
repeatCount=-1 或者infinite 循环了
还可以设成reverse,表示偶数次显示动画时会做与动画文件定义的方向相反的方向动行。
-->
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="80"
android:duration="1000"
android:repeatCount="1"
android:pivotX="50%"
android:pivotY="50%"
android:repeatMode="reverse"
/>
透明度
<!--fromAlpha :起始透明度
toAlpha:结束透明度
1.0表示完全不透明
0.0表示完全透明-->
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.1"
android:toAlpha="0.8"
android:fillAfter="true"
android:duration="2000"/>
组合动画
<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>
附上源码: 源码