Android动画解析(一)-----逐帧动画和补间动画

今天项目又用到了动画,发现之前掌握的那些又遗忘了不少,趁着有时间,再重新捋顺一边。

Android中的动画分为 逐帧动画,补间动画,属性动画 三种.

逐帧动画(Frame Animation)

逐帧动画:就像GIF图片一样,通过一系列的Drawable依次显示来模拟动画效果。

  • 使用方式:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/pic1" android:duration="150" />
    <item android:drawable="@drawable/pic2" android:duration="150" />
    <item android:drawable="@drawable/pic3" android:duration="150" />
</animation-list>

<!--XML文件以<animation-list>为根元素,
以<item>表示要轮换显示的图片,
oneshot属性,用于设置播放模式(是单次播放还是循环播放)
duration属性表示各项显示的时间。
XML文件要放在/res/drawable/目录下-->
  • 调用方法:
 AnimationDrawable animationDrawable = (AnimationDrawable) loadingImage.getDrawable();
 animationDrawable.start();//开始动画
 animationDrawable.stop();//结束动画

补间动画(Tween Animation)

补间动画:给出两个关键帧,通过一些算法将给定属性值在给定的时间内在两个关键帧间渐变。
补间动画是使用Animation类创建的,下面的列表说明了四种可用的动画类型:

动画类型简介
AlphaAnimation可以改变View的透明度。(透明度渐变动画)
ScaleAnimation允许缩放选中的View。(缩放动画)
RotateAnimation可以在XY平面上旋转选中的View。(旋转动画)
TranslateAnimation可以在屏幕上移动选中的View。(平移动画)

当View设置补件动画后,动画只是移动了内容,View本身其实还在原地,所以点击事件也还是在原地,如果想让点击事件跟着移动,最简单的是使用属性动画。

TranslateAnimation(平移动画)
java代码写法
TranslateAnimation 
animation = new TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta);

// fromXDelta 属性为动画起始时 X坐标上的位置    toXDelta   属性为动画结束时 X坐标上的位置
// fromYDelta 属性为动画起始时 Y坐标上的位置    toYDelta   属性为动画结束时 Y坐标上的位置
//  没有指定fromXType toXType fromYType toYType 时候, 默认是以自己为相对参照物       

...
View.startAnimation(animation);
XML文件写法

通过配置XML文件来实现平移动画,文件需要放在res\anim目录中,在动画文件中通过<translate>标签设置移动效果。首先在res\anim目录下建一个动画文件

translate_tween.xml,该文件的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"  
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/accelerate_interpolator"   
    android:toXDelta="60"
    android:toYDelta="60" >

</translate>
<!-- android:interpolator     动画差值器-->
<!-- android:duration        动画持续时间,以毫秒为单位 -->
<!-- android:fillAfter       如果设置为true,控件动画结束时,将保持动画最后时的状态-->
<!-- android:fillBefore      如果设置为true,控件动画结束时,还原到开始动画前的状态-->
<!-- android:fillEnabled     与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态-->
<!-- android:repeatCount     重复次数-->
<!-- android:repeatMode      重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。-->
// 在代码中这样调用
Animation animation=AnimationUtils.loadAnimation(this, R.anim.translate_tween);
View.startAnimation(animation);

或者用这种方式
//View.setAnimation(animation);
//animation.start();
TranslateAnimation特有属性

 * android:fromXDelta="0%"   动画开始执行时X轴方向控件的起始位置,
                    * 当value加%时(例如80%),意思是相对于控件的原始位置往右的80%控件宽度的位置  
                    * 又例如value为-20%时,意思是相对于控件的原始位置往左的20%控件宽度的位置。
                    * 当Value不加%时(例如80),表示相对于控件的原始位置往右80个像素(px)的位置,
                    * 又如当Value为-20时,即往左20个像素。  

* android:toXDelta="100%"动画结束执行时X轴方向控件的结束位置,Value可以加%,也可以不加%,原理同上  
* android:fromYDelta="0%"动画开始执行时Y轴方向控件的起始位置,Value可以加%,也可以不加%,原理同上  
* android:toYDelta="100%"动画结束执行时Y轴方向控件的结束位置,Value可以加%,也可以不加%,原理同上  
AlphaAnimation(透明度渐变动画)
Java代码写法
 AlphaAnimation mAlphaAnimation = new AlphaAnimation(float fromAlpha, float toAlpha);
 //fromAlpha:设置动画开始时控件的透明度
  //toAlpha:设置动画结束时的控件的透明度 
  //两个值取值都为0~1之间,0.0为透明,控件不显示,1.0为不透明,控件全部显示 
  ...
  View.startAnimation(mAlphaAnimation);
XML写法

同样文件需要放在res\anim目录中,在动画文件中通过<alpha>标签设置渐变效果。首先在res\anim目录下建一个动画文件
alpha_tween.xml,该文件的内容如下:

<alpha xmlns:android="http://schemas.android.com/apk/res/android"  
        android:fromAlpha= "0.0"  
        android:toAlpha= "1.0"  
        >  
</alpha>  
<!-- android:interpolator     动画差值器-->
<!-- android:duration        动画持续时间,以毫秒为单位 -->
<!-- android:fillAfter       如果设置为true,控件动画结束时,将保持动画最后时的状态-->
<!-- android:fillBefore      如果设置为true,控件动画结束时,还原到开始动画前的状态-->
<!-- android:fillEnabled     与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态-->
<!-- android:repeatCount     重复次数-->
<!-- android:repeatMode      重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。-->
// 在代码中这样调用
Animation animation=AnimationUtils.loadAnimation(this, R.anim.alpha_tween);
View.startAnimation(animation);

或者用这种方式
//View.setAnimation(animation);
//animation.start();
AlphaAnimation特有属性
android:fromAlpha:动画开始时的透明度,变化范围为0.0-1.0,0.0表示完全透明,1.0表示完全不透明
android:toAlpha:动画结束是的透明度,变化范围和意义同上。

RotateAnimation(旋转动画)

Java代码写法
RotateAnimation mRotateAnimation =  new RotateAnimation(float fromDegrees, float toDegrees,  
             int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);

// android:fromDegrees :动画开始时旋转的角度位置,float类型,正值代表顺时针方向度数,负值代码逆时针方向度数
//android:toDegrees : 动画结束时旋转到的角度位置,float类型,正值代表顺时针方向度数,负值代码逆时针方向度数

//android:pivotXType: 确定动画在X轴的中心位置类型。与下面的pivotXValue结合,确定X轴上旋转中心。(取值见下表)

//android:pivotXValue  :旋转点X轴坐标值,float类型,可以是数值、百分数、百分数p三种样式,比如50、50%、50%p
                        //当为数值时,表示在当前View的左上角,即原点处加上50px,做为旋转点X坐标,
                        //如果是50%;表示在当前控件的左上角加上自己宽度的50%做为旋转点X坐标;
                        //如果是50%p,那么就是表示在当前控件的左上角加上父控件宽度的50%做为旋转点X坐标。

//android:pivotYType: 确定动画在Y轴的中心位置类型。取值及意义跟android:pivotXType一样。
//android:pivotYValue:旋转点Y轴坐标值,取值及意义跟android:pivotX一样。

...
View.startAnimation(mRotateAnimation);
pivotXType值效果
Animation.ABSOLUTE默认值,围绕设置动画控件的左上角旋转与pivotXValue = 0,pivotYVaule = 0效果相同
Animation.RELATIVE_TO_PARENT设置动画控件的左上角为坐标原点(0,0),动画旋转轴的坐标为(parent.getWidth*pivotXValue,parent.getHeight*pivotYValue)[parent为view的父控件]负数向左(X轴)/上(Y轴)偏移,正数向右(X轴)/下(Y轴)偏移;
Animation.RELATIVE_TO_SELF设置动画控件的左上角为坐标原点(0,0),动画旋转轴的坐标为(view.getWidth*pivotXValue,view.getHeight*pivotYValue)负数向左(X轴)/上(Y轴)偏移,正数向右(X轴)/下(Y轴)偏移;
XML文件写法

在res\anim目录下建一个动画文件rotate_tween.xml,该文件的内容如下:

    <?xml version="1.0" encoding= "utf-8"?>  
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"  
             android:fromDegrees= "0"  
             android:toDegrees= "360"  
             android:pivotX= "50%"  
             android:pivotY= "50%"  
             >  
    </rotate>  
<!-- android:interpolator=     动画差值器-->
<!-- android:duration        动画持续时间,以毫秒为单位 -->
<!-- android:fillAfter       如果设置为true,控件动画结束时,将保持动画最后时的状态-->
<!-- android:fillBefore      如果设置为true,控件动画结束时,还原到开始动画前的状态-->
<!-- android:fillEnabled     与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态-->
<!-- android:repeatCount     重复次数-->
<!-- android:repeatMode      重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。-->
// 在代码中这样调用
Animation animation=AnimationUtils.loadAnimation(this, R.anim.rotate_tween);
View.startAnimation(animation);

或者用这种方式
//View.setAnimation(animation);
//animation.start();
RotateAnimation特有属性
android:fromDegrees:动画开始时旋转的角度位置,float类型,正值代表顺时针方向度数,负值代码逆时针方向度数
android:toDegrees: 动画结束时旋转到的角度位置,float类型,正值代表顺时针方向度数,负值代码逆时针方向度数
android:pivotX:旋转点X轴坐标,float类型,可以是数值、百分数、百分数p三种样式,比如5050%、50%p,当为数值时,表示在当前View的左上角,即原点处加上50px,做为旋转点X坐标,如果是50%;表示在当前控件的左上角加上自己宽度的50%做为旋转点X坐标;如果是50%p,那么就是表示在当前控件的左上角加上父控件宽度的50%做为旋转点X坐标。
android:pivotY:旋转点Y轴坐标,取值及意义跟android:pivotX一样。

ScaleAnimation(缩放动画)

Java代码写法
ScaleAnimation mScaleAnimation = ScaleAnimation(float fromX, float toX, float fromY,  
        float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
// float fromX 动画起始时 X坐标上的伸缩尺寸 比如1.0代表自身无变化,0.5代表起始时缩小一倍,2.0代表放大一倍
// float toX 动画结束时 X坐标上的伸缩尺寸   
// float fromY 动画起始时Y坐标上的伸缩尺寸   
// float toY 动画结束时Y坐标上的伸缩尺寸   

//android:pivotXType: 确定动画在X轴的中心位置类型。与下面的pivotXValue结合,确定X轴上缩放中心点。。(取值见下表)
// float pivotXValue 动画相对于物件的X坐标的开始位置   
// int pivotYType 动画在Y轴相对于物件位置类型   
// float pivotYValue 动画相对于物件的Y坐标的开始位置   

...
View.startAnimation(mScaleAnimation);
pivotXType值效果
Animation.ABSOLUTE默认值,设置动画控件从左上角缩放,与pivotXValue = 0,pivotYVaule = 0效果相同
Animation.RELATIVE_TO_PARENT设置动画控件的左上角为坐标原点(0,0),动画缩放点的坐标为(parent.getWidth*pivotXValue,parent.getHeight*pivotYValue)【parent为view的父控件】负数向左(X轴)/上(Y轴)偏移,正数向右(X轴)/下(Y轴)偏移;
Animation.RELATIVE_TO_SELF设置动画控件的左上角为坐标原点(0,0),动画所放点的坐标为(view.getWidth*pivotXValue,view.getHeight*pivotYValue)负数向左(X轴)/上(Y轴)偏移,正数向右(X轴)/下(Y轴)偏移;
XML文件写法
<?xml version="1.0" encoding= "utf-8"?>   
<scale xmlns:android="http://schemas.android.com/apk/res/android"  
       android:fromXScale= "2.0"  
       android:toXScale= "1.0"  
       android:fromYScale= "2.0"  
       android:toYScale= "1.0"  
       android:pivotX= "50%"  
       android:pivotY= "50%"  
       >  
</scale> 
<!-- android:interpolator=     动画差值器-->
<!-- android:duration        动画持续时间,以毫秒为单位 -->
<!-- android:fillAfter       如果设置为true,控件动画结束时,将保持动画最后时的状态-->
<!-- android:fillBefore      如果设置为true,控件动画结束时,还原到开始动画前的状态-->
<!-- android:fillEnabled     与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态-->
<!-- android:repeatCount     重复次数-->
<!-- android:repeatMode      重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。-->
// 在代码中这样调用
Animation animation=AnimationUtils.loadAnimation(this, R.anim.rotate_tween);
View.startAnimation(animation);

或者用这种方式
//View.setAnimation(animation);
//animation.start();
ScaleAnimation特有属性
android:fromXScale起始的X方向上相对自身的缩放比例,类型float,比如1.0代表自身无变化,0.5代表起始时缩小一倍,2.0代表放大一倍
android:toXScale:结尾的X方向上相对自身的缩放比例,类型float
android:fromYScale:起始的Y方向上相对自身的缩放比例,类型float
android:toYScale:结尾的Y方向上相对自身的缩放比例,类型float
android:pivotX: 缩放起点X轴坐标,可以是数值、百分数、百分数p ,具体意义roate中已经演示
android:pivotY:缩放起点Y轴坐标,取值及意义与pivotX一样

补间动画设置动画监听事件

mAnimation.setAnimationListener(new AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
                //在动画开始时执行处理
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                //在动画重复时执行处理
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                //在动画完成后执行处理
            }
        });

AnimationSet

AnimationSet 可以让许多个动画在同一时间开始(也就是动画的叠加)
注意 : AnimationSet 和 AnimatorSet 注意区分区别,这里只做AnimationSet讲解。下篇博客讲解AnimatorSet

Java 代码写法
    //创建动画,参数表示他的子动画是否共用一个插值器
        AnimationSet animationSet = new AnimationSet(true);
        //添加动画(可以添加多个,每个动画都可以单独设置属性)
        animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
        animationSet.addAnimation(new TranslateAnimation(0,120 , 0, -300));

        //设置插值器
        animationSet.setInterpolator(new LinearInterpolator());
        //设置动画持续时长
        animationSet.setDuration(3000);
        //设置动画结束之后是否保持动画的目标状态
        animationSet.setFillAfter(true);
        //设置动画结束之后是否保持动画开始时的状态
        animationSet.setFillBefore(false);
        //设置重复模式
        animationSet.setRepeatMode(Animation.REVERSE);
        //设置重复次数
        animationSet.setRepeatCount(Animation.INFINITE);
        //设置动画延时时间
        animationSet.setStartOffset(2000);
        //取消动画
        animationSet.cancel();
        //释放资源
        animationSet.reset();
        //开始动画
        mIvImg.startAnimation(animationSet);
XML文件写法

文件目录:res/anim/animation_set.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:shareInterpolator="true">
    <alpha
        android:duration="2000"
        android:fillAfter="true"
        android:fillBefore="false"
        android:fromAlpha="1.0"
        android:repeatCount="-1"
        android:repeatMode="reverse"
        android:toAlpha="0.0"/>
    <rotate
        android:duration="2000"
        android:fillAfter="true"
        android:fillBefore="false"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="-1"
        android:repeatMode="reverse"
        android:toDegrees="360"/>
    <set
        android:interpolator="@android:anim/bounce_interpolator"
        android:shareInterpolator="true"
        android:startOffset="1000">
        <scale
            android:duration="2000"
            android:fillAfter="true"
            android:fillBefore="false"
            android:fromXScale="1.0"
            android:fromYScale="1.0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:repeatCount="-1"
            android:repeatMode="reverse"
            android:toXScale="2.0"
            android:toYScale="2.0"/>
        <translate
            android:duration="2000"
            android:fillAfter="true"
            android:fillBefore="false"
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:repeatCount="-1"
            android:repeatMode="reverse"
            android:toXDelta="200%"
            android:toYDelta="200%"/>
    </set>
</set>
Java代码中调用  
 AnimationSet animationSet = (AnimationSet)  
                AnimationUtils.loadAnimation(XmlViewAnimationActivity.this, R.anim.animation_set);
 View.startAnimation(animationSet);

差值器效果

AccelerateDecelerateInterpolator============动画开始与结束的地方速率改变比较慢,在中间的时候加速。
AccelerateInterpolator===================动画开始的地方速率改变比较慢,然后开始加速。
AnticipateInterpolator ==================开始的时候向后然后向前甩。
AnticipateOvershootInterpolator=============开始的时候向后然后向前甩一定值后返回最后的值。
BounceInterpolator=====================动画结束的时候弹起。
CycleInterpolator======================动画循环播放特定的次数,速率改变沿着正弦曲线。
DecelerateInterpolator===================在动画开始的地方快然后慢。
LinearInterpolator======================以常量速率改变。
OvershootInterpolator====================向前甩一定值后再回到原来位置。
PathInterpolator========================新增的,就是可以定义路径坐标,然后可以按照路径坐标来跑动;注意其坐标并不是 XY,
而是单方向,也就是我可以从0~1,然后弹回0.5 然后又弹到0.7 有到0.3,直到最后时间结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值