美文网首页程序员
这次彻底搞懂Android补间动画

这次彻底搞懂Android补间动画

作者: 饮水思源为名 | 来源:发表于2018-08-10 17:03 被阅读432次

    作用对象:

    视图控件(View)

    1. AndroidTextView、Button等等
    2. 不可作用于View组件的属性,如:颜色、背景、长度等等

    原理与分类:

    通过确定开始的视图样式 & 结束的视图样式、中间动画变化过程由系统补全来确定一个动画

    1. 结束的视图样式:平移、缩放、旋转 & 透明度样式
    2. 即补间动画的动画效果就是:平移、缩放、旋转 & 透明度动画

    如何使用:

    • 补间动画的使用方式分为两种:在XML 代码 / Java 代码里设置
    1. 前者优点:动画描述的可读性更好
    2. 后者优点:动画效果可动态创建

    平移动画(Translate)

    1. XML实现:
    <?xml version="1.0" encoding="utf-8"?>
    // 采用<translate /> 标签表示平移动画
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
        // 以下参数是4种动画效果的公共属性,即都有的属性
        android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
        android:startOffset ="1000" // 动画延迟开始时间(ms)
        android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
        android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
        android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
        android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
        android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
        android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
        // 以下参数是平移动画特有的属性
        android:fromXDelta="0" // 视图在水平方向x 移动的起始值
        android:toXDelta="500" // 视图在水平方向x 移动的结束值
        android:fromYDelta="0" // 视图在竖直方向y 移动的起始值
        android:toYDelta="500" // 视图在竖直方向y 移动的结束值
        />
    
    img=findViewById(R.id.img);
    Animation translateAnimation= AnimationUtils.loadAnimation(this,R.anim.anim_translate);
    img.startAnimation(translateAnimation);
    
    1. java实现:
    Animation translateAnimation2=new TranslateAnimation(0,500,0,500);
    translateAnimation2.setDuration(3000);
    translateAnimation2.setRepeatCount(Animation.INFINITE);
    img.startAnimation(translateAnimation2);
    
    Translate

    平移动画(Translate)使用心得:

    1. fromXDeltafromYDelta参数均为0时,指的坐标为控件View的左上角。
    2. fromXDeltafromYDelta参数可以写100%,这里得100%指的是控件View自己的宽高度。同时,可以设置n%使得View相对于父布局的宽高移动。

    缩放动画(Scale):

    xml实现:

    <?xml version="1.0" encoding="utf-8"?>
    // 采用<scale/> 标签表示是缩放动画
    <scale  xmlns:android="http://schemas.android.com/apk/res/android"
        // 以下参数是4种动画效果的公共属性,即都有的属性
        android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
        android:startOffset ="1000" // 动画延迟开始时间(ms)
        android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
        android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
        android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
        android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
        android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
        android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
     
       // 以下参数是缩放动画特有的属性
        android:fromXScale="0.0" 
        // 动画在水平方向X的起始缩放倍数
        // 0.0表示收缩到没有;1.0表示正常无伸缩
        // 值小于1.0表示收缩;值大于1.0表示放大
        android:toXScale="2"  //动画在水平方向X的结束缩放倍数
        android:fromYScale="0.0" //动画开始前在竖直方向Y的起始缩放倍数
        android:toYScale="2" //动画在竖直方向Y的结束缩放倍数
        android:pivotX="50%" // 缩放轴点的x坐标
        android:pivotY="50%" // 缩放轴点的y坐标
        // 轴点 = 视图缩放的中心点
        // pivotX pivotY,可取值为数字,百分比,或者百分比p
        // 设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
        // 设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
        // 设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
        // 两个50%表示动画从自身中间开始,具体如下图
        />
    
    两个pivo都为50%和30%的中心点
    Animation scaleAnimation1=AnimationUtils.loadAnimation(this,R.anim.anim_scale);
    img.startAnimation(scaleAnimation1);
    

    java实现:

    Animation scaleAnimation2 = new ScaleAnimation(1,2,1,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnimation2.setDuration(3000);
    scaleAnimation2.setRepeatCount(Animation.INFINITE);
    img.startAnimation(scaleAnimation2);
    
    Scale

    缩放动画使用心得:

    1. 关于PovoteXTypePovoteYType分别设置缩放轴点的x、y坐标缩放模式,设置值为RELATIVE_TO_SELF是我们常见的缩放,相对于自己设置x,y值。根据以(X、Y)坐标点放大缩小。还可以设置值为RELATIVE_TO_PARENT,是党对于父布局。

    旋转动画(Rotate)

    xml实现:

    <?xml version="1.0" encoding="utf-8"?>
    // 采用<rotate/> 标签表示是旋转动画
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
    
        // 以下参数是4种动画效果的公共属性,即都有的属性
        android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
        android:startOffset ="1000" // 动画延迟开始时间(ms)
        android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
        android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
        android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
        android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
        android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
        android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
        
        // 以下参数是旋转动画特有的属性
        android:duration="1000"
        android:fromDegrees="0" // 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
        android:toDegrees="270" // 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
        android:pivotX="50%" // 旋转轴点的x坐标
        android:pivotY="0" // 旋转轴点的y坐标
        // 轴点 = 视图缩放的中心点
    
    // pivotX pivotY,可取值为数字,百分比,或者百分比p
        // 设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
        // 设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
        // 设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
        />
    
    Animation rotateAnimation1=AnimationUtils.loadAnimation(this,R.anim.anim_rotate);
    img.startAnimation(rotateAnimation1);
    

    java实现:

    Animation rotateAnimation2=new RotateAnimation(0,360,RELATIVE_TO_SELF,0.5f,RELATIVE_TO_SELF,0.5f);
    rotateAnimation2.setDuration(3000);
    rotateAnimation2.setRepeatCount(Animation.INFINITE);
    img.startAnimation(rotateAnimation2);
    
    Rotate

    旋转动画使用心得:

    1. 在java实现中,如果没有设置了x,y的,那么设置值得意义是长度。如果设置了模式,例如RELATIVE_TO_SELF,那么值得意义是百分比。

    透明度动画(Alpha)

    xml实现:

    <?xml version="1.0" encoding="utf-8"?>
    // 采用<alpha/> 标签表示是透明度动画
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
    
        // 以下参数是4种动画效果的公共属性,即都有的属性
        android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
        android:startOffset ="1000" // 动画延迟开始时间(ms)
        android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
        android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
        android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
        android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
        android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
        android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
        
        // 以下参数是透明度动画特有的属性
        android:fromAlpha="1.0" // 动画开始时视图的透明度(取值范围: -1 ~ 1)
        android:toAlpha="0.0"// 动画结束时视图的透明度(取值范围: -1 ~ 1)
        />
    
    Animation alphaAnimation1=AnimationUtils.loadAnimation(this,R.anim.anim_alpha);
    img.startAnimation(alphaAnimation1);
    

    java实现:

     Animation alphaAnimation2=new AlphaAnimation(0,1);
    alphaAnimation2.setDuration(3000);
    alphaAnimation2.setRepeatCount(Animation.INFINITE);
    img.startAnimation(alphaAnimation2);
    
    alpha

    组合动画:

      我们刚刚已经了解了单个的动画,但是在日常开发中,很少会出现只是用一个动画就能够达到的需求,我们主要灵活运用上述四种基础部件动画,达到炫酷的效果。
    在xml中实现:

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <rotate
            android:duration="1000"
            android:fromDegrees="0"
            android:toDegrees="360"
            android:pivotX="50%"
            android:repeatCount = "infinite"
            android:pivotY="50%" />
    
        <translate
            android:duration="10000"
            android:fromXDelta="-50%p"
            android:fromYDelta="0"
            android:repeatCount = "infinite"
            android:repeatMode= "reverse"
            android:toXDelta="50%p"
            android:toYDelta="0" />
    
        <alpha
            android:startOffset="1000"
            android:duration="2000"
            android:fromAlpha="1.0"
            android:repeatMode= "reverse"
            android:toAlpha="0.5" />
    
    
        <scale
            android:duration="2000"
            android:fromXScale="1.5"
            android:fromYScale="1.5"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toXScale="1"
            android:toYScale="1"
            android:repeatMode= "reverse"
            android:repeatCount = "infinite"
            />
    </set>
    
    Animation allAnimation1=AnimationUtils.loadAnimation(this,R.anim.anim_all);
    img.startAnimation(allAnimation1);
    

    java实现:

    AnimationSet setAnimation=new AnimationSet(true);
    
    Animation rotate=new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    rotate.setDuration(1000);
    rotate.setRepeatCount(Animation.INFINITE);
    
    Animation translate=new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
                    TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
                    TranslateAnimation.RELATIVE_TO_SELF,0
                    ,TranslateAnimation.RELATIVE_TO_SELF,0);
    translate.setDuration(10000);
    translate.setRepeatCount(Animation.INFINITE);
    translate.setRepeatMode(Animation.REVERSE);
    
    Animation alpha = new AlphaAnimation(1,0.5f);
    alpha.setDuration(2000);
    alpha.setStartOffset(1000);
    alpha.setRepeatMode(Animation.REVERSE);
    
    Animation scale = new ScaleAnimation(1,1.5f,1,1.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scale.setDuration(2000);
    scale.setRepeatCount(Animation.INFINITE);
    scale.setRepeatMode(Animation.REVERSE);
    
    setAnimation.addAnimation(alpha);
    setAnimation.addAnimation(rotate);
    setAnimation.addAnimation(translate);
    setAnimation.addAnimation(scale);
    
    img.startAnimation(setAnimation);
    
    组合动画

    监听动画:

    • Animation类通过监听动画开始 / 结束 / 重复时刻来进行一系列操作,如跳转页面等等
    • 通过在 Java 代码里setAnimationListener()方法设置
    Animation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    // 动画开始时回调
                }
    
                @Override
                public void onAnimationEnd(Animation animation) {
                    // 动画结束时回调
                }
    
                @Override
                public void onAnimationRepeat(Animation animation) {
                    //动画重复执行的时候回调
                }
            });
    

    若采取上述方法监听动画,每次监听都必须重写4个方法。

    • 背景:有些时候我们并不需要监听动画的所有时刻
    • 问题:但上述方式是必须需要重写4个时刻的方法,这显示太累赘
    • 解决方案:采用动画适配器AnimatorListenerAdapter,解决
      实现接口繁琐 的问题
      具体如下:
    anim.addListener(new AnimatorListenerAdapter() {  
    // 向addListener()方法中传入适配器对象AnimatorListenerAdapter()
    // 由于AnimatorListenerAdapter中已经实现好每个接口
    // 所以这里不实现全部方法也不会报错
        @Override  
        public void onAnimationStart(Animator animation) {  
        // 如想只想监听动画开始时刻,就只需要单独重写该方法就可以
        }  
    });
    

    相关文章

      网友评论

        本文标题:这次彻底搞懂Android补间动画

        本文链接:https://www.haomeiwen.com/subject/ewkkbftx.html