android动画_android动画效果 - CSDN
精华内容
参与话题
  • Android中动画详细讲解

    千次阅读 2018-12-07 10:29:35
    Android动画经常会在切换activity、数据加载时会用到动画效果,以前接触的比较少,用的都是封装好的动画效果,自己写的比较少,今天心血来潮想写一个自己设计的动画效果,发现学习动画代码比较简单,但是要实现某些...

    一、前言

    Android动画经常会在切换activity、数据加载时会用到动画效果,以前接触的比较少,用的都是封装好的动画效果,自己写的比较少,今天心血来潮想写一个自己设计的动画效果,发现学习动画代码比较简单,但是要实现某些特定的动画效果需要很多逻辑,感觉就麻烦了,正好把动画animation整理一下。

    二、概述

    Android动画实现一般都用animation,动画包含三大类型View Animation,帧动画(Drawable Animation),Property Animation(属性动画);属性动画比较好用,可以重点关注一下。

    三、View Animation

    只能被用来设置View的动画,动画效果包含四个子类:(位置(TranslateAnimation)、大小(ScaleAnimation)、旋转(RotateAnimation)、透明度(AlphaAnimation);实现View动画的方式有两种,一种是在xml中直接写动画效果,一种是在activity代码中写。

    注意:动画效果有一个很大的问题,就是当移动到指定位置后,点击该位置是无效的,只能点击原来的位置才有效,它并不是真的移动到该位置了,可以通过下面的属性动画来解决。

    (1)xml编辑动画的方式:

    1、首先在res\anim文件夹下创建xml,

    <?xml version="1.0" encoding="utf-8"?>
    <!--interpolator:差值器,表示动画运行时的时间正常方式,fillAfter:表示动画停留在最后运动的结果-->
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true"
        android:interpolator="@android:anim/decelerate_interpolator">
        <!--透明度标签:表示透明0到不透明1之间的变换-->
        <alpha
            android:fromAlpha="0.0"
            android:toAlpha="1.0" >
        </alpha>
        <!--旋转标签:fromDegrees:表示旋转角度的起始角度,toDegrees:结束角度。pivotX:表示旋转的X轴坐标;pivotY:表示旋转的Y轴坐标-->
        <rotate
            android:fromDegrees="0.0"
            android:toDegrees="720"
            android:pivotX="50%"
            android:pivotY="50%"/>
        <!--缩放标签:fromXScale,toXScale表示水平缩放的起始值和结束值;fromYScale,toYScale竖直方向的缩放起始值和结束值。
        pivotX,pivotY,表示缩放动画效果的基准点x,y轴
        -->
        <scale
            android:fromXScale="0.4"
            android:fromYScale="0.4"
            android:toXScale="1.2"
            android:toYScale="1.2"
            android:pivotX="50%"
            android:pivotY="50%">
        </scale>
        <!--移动标签:fromXDelta,toXDelta表示x轴移动的像素点;fromYDelta,toYDelta表示Y轴移动的像素点-->
        <translate
            android:fromXDelta="0"
            android:toXDelta="300"
            android:fromYDelta="0"
            android:toYDelta="300"
            >
        </translate>
    </set>

    2、在activity代码中调用animation,实现动画效果

       /*xml自定义动画功能*/
        fun setXmlAnimation(){
            //加载xml动画
            var xmlAnimation=AnimationUtils.loadAnimation(this,R.anim.animation_all)
            //设置动画播放时长
            xmlAnimation.duration=2000
            photo_id?.startAnimation(xmlAnimation)
        }

    (2) 通过代码实现动画效果

     

    代码实现动画效果的属性其实和在xml中写差不多,但是在代码中写会更加灵活,可以更好的设置重复次数,可以根据加载view的长宽来动态加载移动的位置。

    1、实现代码如下:

        /*代码实现动画的四个功能*/
        fun blendAnimation(){
            /*
         *  创建一个AnimationSet,它能够同时执行多个动画效果
         *  构造方法的入参如果是“true”,则代表使用默认的interpolator,如果是“false”则代表使用自定义interpolator
         */
            val mAnimationSet = AnimationSet(true)
            //透明度动画,从完全透明到不透明,我们的动画都是float型的,所以,在写数字的时候,要加f
            val alphAnima = AlphaAnimation(0.0f, 1.0f)
            /*
         *  创建一个旋转动画对象
         *  入参列表含义如下:
         *  1.fromDegrees:从哪个角度开始旋转
         *  2.toDegrees:旋转到哪个角度结束
         *  3.pivotXType:旋转所围绕的圆心的x轴坐标的类型,有ABSOLUT绝对坐标、RELATIVE_TO_SELF相对于自身坐标、RELATIVE_TO_PARENT相对于父控件的坐标
         *  4.pivotXValue:旋转所围绕的圆心的x轴坐标,0.5f表明是以自身这个控件的一半长度为x轴
         *  5.pivotYType:y轴坐标的类型
         *  6.pivotYValue:y轴坐标
         */
            val rotateAnim = RotateAnimation(0f, 720f, Animation.RELATIVE_TO_SELF, 0.5f,
                    Animation.RELATIVE_TO_SELF, 0.5f)
    
            /*
         *  创建一个缩放效果的动画
         *  入参列表含义如下:
         *  fromX:x轴的初始值
         *  toX:x轴缩放后的值
         *  fromY:y轴的初始值
         *  toY:y轴缩放后的值
         *  pivotXType:x轴坐标的类型,有ABSOLUT绝对坐标、RELATIVE_TO_SELF相对于自身坐标、RELATIVE_TO_PARENT相对于父控件的坐标
         *  pivotXValue:x轴的值,0.5f表明是以自身这个控件的一半长度为x轴
         *  pivotYType:y轴坐标的类型
         *  pivotYValue:轴的值,0.5f表明是以自身这个控件的一半长度为y轴
         */
            var scaleAnimation = ScaleAnimation(0f,1f,0f,1f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    /*
         *  创建一个移动动画效果
         *  入参的含义如下:
         *  fromXType:移动前的x轴坐标的类型
         *  fromXValue:移动前的x轴的坐标
         *  toXType:移动后的x轴的坐标的类型
         *  toXValue:移动后的x轴的坐标
         *  fromYType:移动前的y轴的坐标的类型
         *  fromYValue:移动前的y轴的坐标
         *  toYType:移动后的y轴的坐标的类型
         *  toYValue:移动后的y轴的坐标
         */
            var translateAnimation = TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.ABSOLUTE,360f,
                    Animation.RELATIVE_TO_SELF,0f,Animation.ABSOLUTE,360f)
    
            mAnimationSet.addAnimation(alphAnima)
            mAnimationSet.addAnimation(rotateAnim)
            mAnimationSet.addAnimation(scaleAnimation)
            mAnimationSet.addAnimation(translateAnimation)
            mAnimationSet.setDuration(2000)//动画持续时间时间
            mAnimationSet.setInterpolator(DecelerateInterpolator()) //添加插值器,下面会有说明
            mAnimationSet.setFillAfter(true)
            photo_id?.startAnimation(mAnimationSet)
        }
    Animation类的方法 解释
    reset() 重置Animation的初始化
    cancel() 取消Animation动画
    start() 开始Animation动画
    setAnimationListener(AnimationListener listener) 给当前Animation设置动画监听
    hasStarted() 判断当前Animation是否开始
    hasEnded() 判断当前Animation是否结束


    既然补间动画只能给View使用,那就来看看View中和动画相关的几个常用方法吧,如下:

    View类的常用动画操作方法 解释
    startAnimation(Animation animation) 对当前View开始设置的Animation动画
    clearAnimation() 取消当View在执行的Animation动画

    setInterpolator差值器的说明:也可以自定义差值器

    java类 xml id值 描述
    AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 动画始末速率较慢,中间加速
    AccelerateInterpolator @android:anim/accelerate_interpolator 动画开始速率较慢,之后慢慢加速
    AnticipateInterpolator @android:anim/anticipate_interpolator 开始的时候从后向前甩
    AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 类似上面AnticipateInterpolator
    BounceInterpolator @android:anim/bounce_interpolator 动画结束时弹起
    CycleInterpolator @android:anim/cycle_interpolator 循环播放速率改变为正弦曲线
    DecelerateInterpolator @android:anim/decelerate_interpolator 动画开始快然后慢
    LinearInterpolator @android:anim/linear_interpolator 动画匀速改变
    OvershootInterpolator @android:anim/overshoot_interpolator 向前弹出一定值之后回到原来位置
    PathInterpolator   新增,定义路径坐标后按照路径坐标来跑。

    2、帧动画(Drawable Animation)

    Drawable动画其实就是Frame动画(帧动画),它允许你实现像播放幻灯片一样的效果,这种动画的实质其实是Drawable,所以这种动画的XML定义方式文件一般放在res/drawable/目录下,但是容易引起内存溢出,只适合小型图片的播放功能:

    <?xml version="1.0" encoding="utf-8"?>
    <!--
    	根标签为animation-list,其中oneshot代表着是否只展示一遍,设置为false会不停的循环播放动画
    	根标签下,通过item标签对动画中的每一个图片进行声明
    	android:duration 表示展示所用的该图片的时间长度
     -->
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false" >
        <item android:drawable="@drawable/wifi1" android:duration="500"/>
        <item android:drawable="@drawable/wifi2" android:duration="500"/>
        <item android:drawable="@drawable/wifi3" android:duration="500"/>
        <item android:drawable="@drawable/wifi4" android:duration="500"/>
        <item android:drawable="@drawable/wifi5" android:duration="500"/>
    </animation-list>

    java代码:

      var animDrawable = ContextCompat.getDrawable(this,R.drawable.drawle_animation) as AnimationDrawable
            photo_id?.background=animDrawable
            animDrawable.start()

     

    四、Property Animation(属性动画)

    相对于View animation,功能更加强大的。而且是真正的视图移动,点击移动后的视图会有点击效果。属性动画有两个类:ValueAnimatorObjectAnimator。

    ValueAnimator:可以设置开始值和结束值来动态改变view的移动位置

    ObjectAnimator:功能更加强大,可以控制位移、透明度、旋转、缩放。

    1、ValueAnimator的使用

    移动的时候使用,使用起来较简单,代码如下

        fun playAnimation(){
            //获得xml中TextView的宽度和高度
            val spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            photo_id.measure(spec, spec)
            val measuredWidth = photo_id.measuredWidth
            val measuredHeight = photo_id.measuredHeight
            // ofInt(),其中还包括ofFloat,区别只是写入的内容不同,作用有:
            // 1. 创建动画实例
            // 2. 将传入的多个Int参数进行平滑过渡:此处传入0和400,表示将值从0平滑过渡到400
            // 如果传入了3个Int参数 a,b,c ,则是先从a平滑过渡到b,再从b平滑过渡到C,以此类推
            // ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置,即默认设置了如何从初始值 过渡到 结束值
            anim= ValueAnimator.ofInt(0,400)
            // 设置动画的播放各种属性
            // 设置动画运行的时长
            anim?.duration=5000
            // 设置动画延迟播放时间
            anim?.startDelay=1000
            // 设置动画重复播放次数 = 重放次数+1
            // 动画播放次数 = infinite时,动画无限重复
            anim?.repeatCount=0
            // 设置重复播放动画模式
            // ValueAnimator.RESTART(默认):正序重放
            // ValueAnimator.REVERSE:倒序回放
            anim?.repeatMode=ValueAnimator.RESTART
            //动画改变监听器,5ms/帧
            anim?.addUpdateListener { animation ->
                // 获得改变后的值
                var curValue : Int=animation.animatedValue as Int
                Log.i("feng","时间值____"+curValue)
                // 将改变的值手动赋值给对象的属性值:通过动画的更新监听器
                // 设置 值的更新监听器
                // 即:值每次改变、变化一次,该方法就会被调用一次
                // 输出改变后的值:依次代表控件的左端、顶端、右端、和底端
                photo_id?.layout(curValue,curValue,curValue+measuredWidth,curValue+measuredHeight)
            }
            anim?.start()
            // 启动动画
        }

    顺便记录一下在xml写动画效果的方法,该方法不如用kotlin代码写灵活,不太复杂的动画可以使用。

    // ValueAnimator采用<animator>  标签
    <animator xmlns:android="http://schemas.android.com/apk/res/android"  
        android:valueFrom="0"   // 初始值
        android:valueTo="100"  // 结束值
        android:valueType="intType" // 变化值类型 :floatType & intType
    
        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 // 插值器,即影响动画的播放速度。
    
    />  
    
    在Java代码中启动动画
    Animator animator = AnimatorInflater.loadAnimator(context, R.animator.set_animation);  
    // 载入XML动画
    
    animator.setTarget(view);  
    // 设置动画对象
    
    animator.start();  
    // 启动动画

    2、ObjectAnimator

    可实现平移、旋转、透明度、颜色、背景色等。

    效果图如下:

    实现代码:

        /*ObjectAnimator的使用*/
        fun playObjectAnimation(){
            val set = AnimatorSet()
            //控制透明度的,我用ofInt没好使,还是用float吧
            var animator1=ObjectAnimator.ofFloat(photo_id,"alpha",0f,1f)
            animator1?.duration=2000
            //延X轴移动
            var animator2=ObjectAnimator.ofFloat(photo_id,"translationX",0f,300f)
            animator2?.duration=2000
            animator2?.interpolator=DecelerateInterpolator()
            //延y轴移动,起始位置和结束位置
            var animator3=ObjectAnimator.ofFloat(photo_id,"translationY",0f,500f,200f)
            animator3?.duration=2000
            animator3?.interpolator=DecelerateInterpolator()
            //沿X轴旋转
            var animator4=ObjectAnimator.ofFloat(photo_id,"rotationX",0f,720f)
            animator4?.duration=2000
            //沿Y轴旋转
            var animator5=ObjectAnimator.ofFloat(photo_id,"rotationY",0f,720f)
            animator5?.duration=2000
            //缩放,可以根据X轴和Y轴缩放
            var animator6=ObjectAnimator.ofFloat(photo_id,"scaleX",0f,4f,2f)
            animator6?.duration=3000
            //改变颜色
            var animator7=ObjectAnimator.ofInt(photo_id,"backgroundColor",Color.RED, Color.BLUE, Color.GRAY, Color.GREEN)
            animator7?.duration=2000
            set.play(animator1).before(animator2) //先执行anim动画之后在执行anim2
            set.play(animator2).before(animator3)
            set.play(animator3).before(animator4)
            set.play(animator4).before(animator5)
            set.play(animator5).before(animator6)
            set.play(animator6).before(animator7)
            set.start()
        }

     

    展开全文
  • Android三大动画使用总结

    千次阅读 2019-05-28 11:23:31
    动画Android开发比较常用,主要有:帧动画、补间动画、属性动画(3.0增加),下面开始学习: 一、Frame Animation 1、简介 Frame Animation,逐帧动画是一种常见的动画形式,其原理是在“连续的关键帧”分解...

    动画在Android开发中比较常用,主要有:帧动画、补间动画、属性动画(3.0增加),下面开始学习:

    一、Frame Animation


    1、简介

    Frame Animation,逐帧动画是一种常见的动画形式,其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。

    简单理解:
    连续播放准备好的关键帧图片,形成动画

    2、xml实现

    先创建帧动画文件

    // res/drawable/anim_frame.xml
    
    <?xml version="1.0" encoding="utf-8"?>
    <animation-list
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
        <!-- 帧动画
             以 animation-list 为根节点
             oneshot : 是否只播放一次
             duration : 每张图片持续时间
         -->
        <item
            android:drawable="@drawable/smoke1"
            android:duration="200"/>
        <item
            android:drawable="@drawable/smoke2"
            android:duration="200"/>
            
        …… 其余item省略
    </animation-list>
    

    设置动画

    // 2. 将动画设置给 iv,二选一
        // 2.1 设置成图片资源
        mIv.setImageResource(R.drawable.anim_frame);
    
        // 2.2 设置成背景资源,如果单纯想显示动画,就把src图片去掉,否则就是图片会盖在动图上面,因为是背景
        // mIv.setBackgroundResource(R.drawable.anim_frame);
    
    // 3. 获取动画,根据设置动画方式,二选一
        // 3.1 设置为图片资源的获取方式
        mAnimDrawable = (AnimationDrawable) mIv.getDrawable();
        
        // 3.2 设置为背景资源的获取方式
        // mAnimDrawable2 = (AnimationDrawable) mIv.getBackground();
    
    // 4. 也可在代码中设置 是否播放一次
    mAnimDrawable.setOneShot(false);
    
    /**
     * 开始动画
     * @param view
     */
    public void startAnim(View view) {
        mAnimDrawable.start();
    }
    
    /**
     * 停止动画
     * @param view
     */
    public void stopAnim(View view) {
        mAnimDrawable.stop();
    }
    

    3、代码实现

    // 1. 创建 AnimationDrawable 对象
    mAnimDrawable = new AnimationDrawable();
    
    // 2. 设置是否播放一次
    mAnimDrawable.setOneShot(false);
    
    // 3. 添加帧
    for (int i = 1; i < 23; i++) {
        int id = getResources().getIdentifier("smoke" + i, "drawable", getPackageName());
        Drawable drawable = ContextCompat.getDrawable(this, id);
        // 添加帧图片,并设置每帧持续时间
        mAnimDrawable.addFrame(drawable, 200);
    }
    
    // 4. iv 设置动画对象
        // 4.1 设置为图片资源
        mIv.setImageDrawable(mAnimDrawable);
        // 4.2 设置为背景资源
        // mIv.setBackgroundDrawable(mAnimDrawable);
    
    /**
     * 开始动画
     * @param view
     */
    public void startAnim(View view) {
        mAnimDrawable.start();
    }
    
    /**
     * 停止动画
     * @param view
     */
    public void stopAnim(View view) {
        mAnimDrawable.stop();
    }
    

    效果图:

    4、要点

    1. 帧动画主要使用AnimationDrawable对象
    1. 作用对象:view
    2. 本质:播放事先准备好的一张张图片
    3. stop()停止在当前帧,已经停止调用无效果
    4. start()从第一帧开始播放,正在播放调用无效果
    5. 设置为图片资源,自动播放;设置为背景资源,需手动播放
    6. 避免使用较大的图片而引起OOM

    你可能需要的:在线GIF分解

    二、Tween Animation


    1、简介

    Tween Animation,补间动画指的是做flash动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动;插入补间动画两个关键帧后,之间的插补帧是由计算机自动运算而得到的。

    简单理解:
    需要定义开始与结束两个关键帧,指定好运动的方式与时间,系统就会自动计算加入中间帧进行播放,形成动画

    2、分类和属性

    分类:

    xml 标签 java 对象 功能
    alph AlphaAnimation 透明度动画
    rotate RotateAnimation 旋转动画
    translate TranslateAnimation 位移动画
    scale ScaleAnimation 缩放动画
    set AnimationSet 补间动画集合

    属性:

    xml 属性 功能 可用于动画
    duration 动画持续时间 ALL
    startOffset 动画开始延迟时间 ALL
    fillBefore 动画完成后,保持动画前状态,默认true ALL
    fillAfter 动画完成后,保持动画后状态,默认false ALL
    fillEnabled 是否使用fillBefore值,对fillAfter值无影响,默认为true ALL
    repeatMode 重放,restart正序重放,reverse倒序回放,默认restart ALL
    repeatCount 重放次数,播放次数=重放次数+1,infinite为无限播放 ALL(set使用无效)
    interpolator 插值器 ALL
    fromAlpha 开始时透明图(0.0~1.0) Alpha
    toAlpha 结束时透明图(0.0~1.0) Alpha
    fromDegrees 开始时角度 Rotate
    toDegrees 结束时角度 Rotate
    fromXDelta 动画起始x轴位置 Translate
    toXDelta 动画结束x轴位置 Translate
    fromYDelta 动画起始y轴位置 Translate
    toYDelta 动画结束y轴位置 Translate
    fromXScale 开始x轴方向缩放值 Scale
    toXScale 结束时x轴方向缩放值 Scale
    fromYScale 开始y轴方向缩放值 Scale
    toYScale 开始y轴方向缩放值 Scale
    pivotX 旋转、缩放中心点x坐标 Rotate、Scale
    pivotY 旋转、缩放中心点y坐标 Rotate、Scale
    shareInterpolator 共享插值器 Set

    注意:

    通过Xml创建动画时

    1、位置变化相关属性

    取值类型为:float, fraction 的属性,需要注意:

    • 设置为数字时(如50,0.5),轴点为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

    2、缩放相关属性

    取值类型为dimension, float, fraction的属性 ,需要注意:

    • dimension:如50dp,表示view的x轴(宽)或y轴(高)为50dp

    • float、百分比:如0.5、50%,同等效果,表示View当前宽高为原大小的50%

    • 百分比p:如50%p,表示View当前宽高为父容器的50%

    查看属性取值类型:点击属性使属性获取焦点,鼠标悬浮在属性上等待一会即可。

    如果没有,可参考Android studio 3.1 基础设置 > 快速文档设置

    3、AlphaAnimation

    透明度动画

    • xml实现 (在res/anim下创建)
    // 1. 创建动画文件
    <?xml version="1.0" encoding="utf-8"?>
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromAlpha="1.0"
        android:toAlpha="0.2"
    
        android:duration="500"
        android:startOffset="500"
        android:fillAfter="false"
        android:repeatMode="restart"
        android:repeatCount="1"
        android:interpolator="@android:anim/linear_interpolator">
    </alpha>
    
    // 2. 加载动画
    Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_sample);
    
    // 3. 设置动画作用对象并开始动画播放
    mView.startAnimation(animation);
    
    • java实现
    // 1. 创建动画,并设置相关属性
    AlphaAnimation animation = new AlphaAnimation(1.0f,0.2f);
    animation.setDuration(500);
    animation.setStartOffset(500);
    animation.setFillAfter(false);
    animation.setRepeatCount(1);
    animation.setRepeatMode(Animation.RESTART);
    animation.setInterpolator(new AccelerateDecelerateInterpolator());
    
    // 2. 设置动画作用对象并开始动画播放
    mView.startAnimation(animation);
    

    4、RotateAnimation

    旋转动画

    <?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%"
    
        android:duration="500"
        android:startOffset="500"
        android:fillAfter="false"
        android:repeatMode="restart"
        android:repeatCount="1"
        android:interpolator="@android:anim/accelerate_interpolator">
    
    </rotate>
    

    5、TranslateAnimation

    位移动画

    <?xml version="1.0" encoding="utf-8"?>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromXDelta="-30%p"
        android:toXDelta="30%p"
        android:fromYDelta="0"
        android:toYDelta="0"
    
        android:duration="500"
        android:startOffset="500"
        android:fillAfter="false"
        android:repeatMode="restart"
        android:repeatCount="1"
        android:interpolator="@android:anim/accelerate_interpolator">
    </translate>
    

    6、ScaleAnimation

    缩放动画

    <?xml version="1.0" encoding="utf-8"?>
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromXScale="100%p"
        android:toXScale="0.8"
        android:fromYScale="100%p"
        android:toYScale="0.8"
        android:pivotY="0%"
        android:pivotX="0%"
    
        android:duration="500"
        android:startOffset="500"
        android:fillAfter="false"
        android:repeatMode="restart"
        android:repeatCount="1"
        android:interpolator="@android:anim/accelerate_interpolator">
    </scale>
    

    7、AnimationSet

    动画集合

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:fillAfter="false"
        android:interpolator="@android:anim/overshoot_interpolator"
        android:repeatMode="reverse"
        android:shareInterpolator="true"
        android:startOffset="500">
    
        <rotate
            android:fromDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:repeatCount="1"
            android:toDegrees="360" />
    
        <scale
            android:fromXScale="50%"
            android:fromYScale="50%"
            android:pivotX="50%"
            android:pivotY="50%"
            android:repeatCount="1"
            android:toXScale="100%"
            android:toYScale="100%" />
    
        <translate
            android:fromXDelta="-30%p"
            android:fromYDelta="0"
            android:repeatCount="1"
            android:toXDelta="30%p"
            android:toYDelta="0" />
    
        <alpha
            android:fromAlpha="1"
            android:repeatCount="1"
            android:toAlpha="0.2" />
    </set>
    

    注意:

    1. Set种各个动画创建的顺序,会影响最后的效果。经过反复测试,rotatescale都要在translate之前
    2. repeatCountSet设置不起作用,需要单独各个设置

    Java代码创建动画的方式,只示例了AlphaAnimation,其它的都类似,只有AnimationSet特殊一点,如下:

    AnimationSet set = new AnimationSet(true);
    // 需要将一个个子动画添加进来
    set.addAnimation(anim1);
    set.addAnimation(anim2);
    set.addAnimation(anim3);
    // ...... 其他类似
    

    8、监听动画

    Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.test);
    animation.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            Log.e("补间动画","动画开始了");
        }
    
        @Override
        public void onAnimationEnd(Animation animation) {
            Log.e("补间动画","动画结束了");
        }
    
        @Override
        public void onAnimationRepeat(Animation animation) {
            Log.e("补间动画","动画重复播放了");
        }
    });
    mView.setAnimation(animation);
    

    效果

    三、 Property Animatin


    本篇暂只介绍属性动画的基本使用,实现补间动画的效果,高级使用方法后续再学习

    1、简介

    属性动画,3.0之前只有帧动画和补间动画,但是由于这两种动画的动画效果只能作用于View,效果简单并且只改变了View的视觉效果,实际上属性并没有改变,所以在3.0引入了属性动画。

    属性动画的工作原理:

    在动画持续时间间隔内,通过不断对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在该属性上的动画效果,可以是任意对象的任意属性

    主要类:

    • ViewPropertyAnimator
    • ObjectAnimator
    • ValueAnimator
    • PropertyValuesHolder
    • AnimatorSet

    2、特点

    • 可作用于任意Java对象
    • 可定义各种复杂的动画效果
    • 真实改变作用对象的属性

    3、ViewPropertyAnimator

    该对象的使用是通过Android 3.1系统上新增的一个方法View#animate()方法获取实例。

    特点

    • 属性动画简化版,只针对View特定属性,但可以实现补间动画所有效果
    • 简便,链式调用,可同时设置多个动画,自动开始动画
    • 性能更好,多个动画是一次同时变化,只执行一次UI刷新

    属性

    View的方法 功能 ViewPropertyAnimator的方法
    setTranslationX() 设置x轴偏移 translationX() translationXBy()
    setTranslationY() 设置y轴偏移 translationY() translationYBy()
    setTranslationZ() 设置z轴偏移 translationZ() translationZBy()
    setX() 设置x轴绝对位置 x() xBy()
    setY() 设置y轴绝对位置 y() yBy()
    setZ() 设置z轴绝对位置 z() zBy()
    setRotation() 设置平面旋转 rotation() rotationBy()
    setRotationX() 设置绕x轴旋转 rotationX() rotationXBy()
    setRotationY() 设置绕y轴旋转 rotationY() rotationYBy()
    setScaleX() 设置横向缩放 scaleX() scaleXBy()
    setScaleY() 设置纵向缩放 scaleY() scaleYBy()
    setAlpha() 设置透明度 alpha() alphaBy()

    说明:

    • translationX(50) :设置view的translationX属性渐变(动画)为50
    • translationXBy(50) :设置设置view的translationX属性渐变(动画)增加50

    使用

    /**
     * button点击事件
     */
     public void viewPropertyAnimator(View view) {
     
        // 因为监听事件需要API 21,为了链式调用,直接在这里进行判断了
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        
            iv.animate() // 获取ViewPropertyAnimator
                    .translationXBy(50) // 每次点击时x轴递增平移;如果是translationX(50)再次点击不会有效果
                    .rotationBy(90) // 平面旋转,同上
                    .setDuration(500) // 动画时长
                    .setStartDelay(1000) // 开始延迟
                    .setInterpolator(new LinearInterpolator()) // 设置插值器,默认AccelerateDecelerateInterpolator
                    .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation) {
                            float animatedValue = (float) animation.getAnimatedValue();
                            // 动画更新监听事件,可获取计算出的【完成度】
                            Log.e("完成度",animatedValue+"   translationX:"+(50*animatedValue) + "   rotation:"+(90*animatedValue));
    
                            // 属性动画,(left,top,right,bottom)是不变的,变化的是(x,y,translationX,translationY) , x = left + translationX
                            Log.d("属性值变化", "getLeft=" + iv.getLeft() + " getX=" + iv.getX() +" getTranslationX=" + iv.getTranslationX());
    
                        }
                    });
        }
    }
    

    效果

    上面Log中间处省略。ViewPropertyAnimator大概使用如上,其他的动画效果实现也一样,API很简单,练习一下就OK了

    4、ObjectAnimator

    该对象的特点就完全对应上面第2点所说属性动画的全部特点了,可以作用任意java对象,不过要有相应的setter/getter方法;通过ObjectAnimator.ofxxx()获取ObjectAnimator对象;该对象会根据动画时长自动计算某一时刻的属性值,自动赋值;需要手动调用start()方法播放动画

    java实现

    public void objectAnimator(View view) {
        // 获取ObjectAnimator
        // 参数1:作用对象
        // 参数2:作用属性,例:setTranslationX -> "translationX" ; setRotationX -> "rotationX",我们的ofFloat也是根据该属性的setter方法参数类型使用的,如果是int,那么我们需要使用ofInt
        // 参数3:可变长参数,-150为开始值 ,0为转接点值 ,150为结束值
        ObjectAnimator animator = ObjectAnimator.ofFloat(iv,"translationX",-150,0,150);
        // 时长
        animator.setDuration(1000);
        // 延迟
        animator.setStartDelay(1000);
        // 重复次数,播放次数 = 重复次数 + 1
        animator.setRepeatCount(0);
        // 重复模式,RESTART:重新开始; REVERSE:反转回来
        animator.setRepeatMode(ValueAnimator.RESTART);
        // 插值器
        animator.setInterpolator(new LinearInterpolator());
        // 动画更新监听
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 可获取计算出【当前时刻的属性值】
                float animatedValue = (float) animation.getAnimatedValue();
                Log.e("当前属性值",animatedValue+"");
    
                // 属性动画,(left,top,right,bottom)是不变的,变化的是(x,y,translationX,translationY) , x = left + translationX
                Log.d("属性值变化", "getLeft=" + iv.getLeft() + " getX=" + iv.getX() +" getTranslationX=" + iv.getTranslationX());
            }
        });
        // 开始动画
        animator.start();
    
    }
    
    

    xml实现

    <!-- res/animator目录下创建,各属性含义对比上面 -->
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:propertyName="translationX"
            android:valueType="floatType"
            android:valueFrom="-150"
            android:valueTo="150"
            android:duration="1000"
            android:startOffset="1000"
            android:repeatCount="0"
            android:repeatMode="restart"
            android:interpolator="@android:anim/linear_interpolator"/>
    </set>
    
    public void objectAnimator(View view) {
        // 加载动画
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.translation);
        // 作用对象
        animator.setTarget(iv);
        // 开始动画
        animator.start();
    
    }
    
    

    效果



    上图Log,中间有省略

    其他动画效果实现方式类似

    组合动画: 借助PropertyValuesHolder实现

     public void objectAnimator(View view) {
        // PropertyValuesHolder此类包含有关属性的信息以及该属性在动画期间应采用的值。 
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.2f, 1);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.2f, 1);
        PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat("rotation", 0, 360);
        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0.2f, 1);
    
        // 获取ObjectAnimator
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(iv, scaleX, scaleY, rotation, alpha);
        
        // 开始动画
        animator.setDuration(2000)
                .start();
    
    }
    
    

    效果

    5、ValueAnimator

    属性动画中最核心的一个类,此类提供了一个简单的计时引擎,用于运行动画时计算动画值,使用这个类,需要我们手动赋值属性值

    xml实现

    // res/animator目录下创建
    <?xml version="1.0" encoding="utf-8"?>
    <animator xmlns:android="http://schemas.android.com/apk/res/android"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="360"
        android:duration="2000"
        android:startOffset="1000"
        android:repeatCount="0"
        android:repeatMode="restart"
        android:interpolator="@android:anim/cycle_interpolator"/>
    
    // 加载动画
    ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.valueanimator);
    

    java实现

    // 获取对象,参数为可变长参数,指定开始值,转接点值,结束值
    ValueAnimator animator = ValueAnimator.ofFloat(0, 90, 180, 360);
    // 时长
    animator.setDuration(2000);
    // 延迟
    animator.setStartDelay(1000);
    // 重复次数
    //        animator.setRepeatCount(0);
    // 重复模式,RESTART:重新开始; REVERSE:反转回来
    //        animator.setRepeatMode(ValueAnimator.RESTART);
    // 插值器
    animator.setInterpolator(new CycleInterpolator(1f));
    

    设置属性值

    // 动画更新监听
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            // 可获取计算出【当前时刻的属性值】
            float animatedValue = (float) animation.getAnimatedValue();
            Log.e("当前属性值", animatedValue + "");
    
            iv.setRotation(animatedValue);
            iv.setTranslationX(animatedValue);
    
            // 属性动画,(left,top,right,bottom)是不变的,变化的是(x,y,translationX,translationY) , x = left + translationX
            Log.d("属性值变化", "getLeft=" + iv.getLeft() + " getX=" + iv.getX() + " getTranslationX=" + iv.getTranslationX());
    
            // 刷新视图
            iv.requestLayout();
    
        }
    });
    // 开始动画
    animator.start();
    

    效果




    上图Log,中间有省略

    组合动画一:自己实现
    上面的动画组合算是凑巧,下面用另一种方式实现

     public void valueAnimator(View view) {
        // 这里我们设置为 0~1
        ValueAnimator animator = ValueAnimator.ofFloat(0,1);
        // 时长
        animator.setDuration(2000);
        // 延迟
        animator.setStartDelay(1000);
        // 插值器
        animator.setInterpolator(new CycleInterpolator(1f));
        // 动画更新监听
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 可获取计算出【当前时刻的属性值】,我们当做比例来用
                float animatedValue = (float) animation.getAnimatedValue();
                
                // 2s内,平面旋转0~360 
                iv.setRotation(animatedValue * 360);
    
                // 2s内,x轴位移,translationX为0~360 
                iv.setTranslationX(animatedValue * 360);
    
                // 2s内,横向缩放 0.2~1.2
                iv.setScaleX((float) (animatedValue+0.2));
    
                // 2s内,纵向缩放 0.2~1.2
                iv.setScaleY((float) (animatedValue+0.2));
    
                // 刷新视图
                iv.requestLayout();
    
            }
        });
        // 开始动画
        animator.start();
    
    }
    

    组合动画二:借助PropertyValuesHolder实现

    public void valueAnimator(View view) {
    	// PropertyValuesHolder此类包含有关属性的信息以及该属性在动画期间应采用的值。 
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.2f, 1.2f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.2f, 1.2f);
        PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat("rotation", 0, 360);
        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("translationX", 0, 360);
    
        ValueAnimator valueAnimator = ValueAnimator.ofPropertyValuesHolder(scaleX, scaleY, rotation, alpha);
        valueAnimator.setDuration(2000);
        valueAnimator.setInterpolator(new CycleInterpolator(1f));
    
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
    
                PropertyValuesHolder[] values = animation.getValues();
    
                for (int i = 0; i < values.length; i++) {
                    // 通过PropertyValuesHolder#getPropertyName() 可获得设置的属性
                    // 通过ValueAnimator#getAnimatedValue("属性") 可获得计算出的当前时刻属性值
                    Log.e("holder", values[i].getPropertyName() + "  " + animation.getAnimatedValue(values[i].getPropertyName()));
    
                    iv.setScaleX((float)animation.getAnimatedValue("scaleX"));
                    iv.setScaleY((float)animation.getAnimatedValue("scaleY"));
                    iv.setRotation((float)animation.getAnimatedValue("rotation"));
                    iv.setTranslationX((float)animation.getAnimatedValue("translationX"));
    
                }
            }
        });
    
        valueAnimator.start();
    
    }
    

    效果: (上面两种实现方式的最终效果都是一样的)

    6、AnimatorSet

    通过上面的学习我们了解到:ObjectAnimator只能改变一个属性,不能直接实现组合动画,需要借助PropertyValuesHolder才行;ValueAnimator也可以直接实现组合动画,也借助PropertyValuesHolder实现;ViewPropertyAnimator可以很方便的实现组合动画;但是它们都有一个缺点:都只能是几种动画效果同时播放;下面我们学习组合动画的正确姿势AnimatorSet

    API

    AnimatorSet

    • play(Animator anim)
      创建AnimatiorSet.Builder对象

    • playSequentially(Animator… items)
      创建AnimatiorSet.Builder对象,并设置每个动画在上个动画执行完后执行,顺序执行

    • playSequentially(List items)
      同上,只不过是集合形式

    • playTogether(Animator… items)
      创建AnimatiorSet.Builder对象,并设置所有动画同时执行

    • playTogether(Collection items)
      同上,只不过是集合形式

    • setDuration(long duration)
      设置此AnimatorSet的每个子动画的持续时长,优先级高于单独设置

    AnimatiorSet.Builder

    • after(Animator anim)
      将现有动画插入到传入的动画之后执行
    • after(long delay)
      将现有动画延迟指定毫秒后执行
    • before(Animator anim)
      将现有动画插入到传入的动画之前执行
    • with(Animator anim)
      将现有动画和传入的动画同时执行

    Java实现

    public void animatorSet(View view) {
        // 顺序执行 
        AnimatorSet set1 = new AnimatorSet();
        ObjectAnimator translationAnimator1 = ObjectAnimator.ofFloat(iv, "translationX", -300);
        ObjectAnimator translationAnimator2 = ObjectAnimator.ofFloat(iv, "translationY", 600);
        ObjectAnimator translationAnimator3 = ObjectAnimator.ofFloat(iv, "translationX", 300);
        ObjectAnimator translationAnimator4 = ObjectAnimator.ofFloat(iv, "translationY", 0);
        ObjectAnimator translationAnimator5 = ObjectAnimator.ofFloat(iv, "translationX", 0);
    
        set1.playSequentially(translationAnimator1, translationAnimator2, translationAnimator3, translationAnimator4, translationAnimator5);
        // 设置动画时长,这里的时长是每个子动画的时长
        set1.setDuration(1000);
    
    
        // 同时执行
        AnimatorSet set2 = new AnimatorSet();
        ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(iv, "rotationY", 0, 360);
        ObjectAnimator scaleAnimator1 = ObjectAnimator.ofFloat(iv, "scaleX", 0.2f, 1);
        ObjectAnimator scaleAnimator2 = ObjectAnimator.ofFloat(iv, "scaleY", 0.2f, 1);
        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(iv, "alpha", 0.2f, 1);
    
        set2.playTogether(rotationAnimator, scaleAnimator1, scaleAnimator2, alphaAnimator);
        // 设置动画时长,这里的时长是每个子动画的时长
        set2.setDuration(5000);
    
        // 最终组合 , 这里设置时长是每个子动画的时长 , 因为想让set1 和 set2 总时长一样,所以分开设置了
        AnimatorSet set = new AnimatorSet();
        set.playTogether(set1,set2);
        set.start();
    }
    

    xml实现

    <?xml version="1.0" encoding="utf-8"?>
    <!--ordering :together 同时执行 ; sequentially 顺序执行 -->
    <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together">
        <!--同时执行 , 给set设置 duration 属性无效 , 所以单独设置-->
        <set android:ordering="together">
            <objectAnimator
                android:propertyName="rotationY"
                android:valueType="floatType"
                android:valueFrom="0"
                android:valueTo="360"
                android:duration="5000"/>
            <objectAnimator
                android:propertyName="scaleX"
                android:valueType="floatType"
                android:valueFrom="0.2"
                android:valueTo="1"
                android:duration="5000"/>
            <objectAnimator
                android:propertyName="scaleY"
                android:valueType="floatType"
                android:valueFrom="0.2"
                android:valueTo="1"
                android:duration="5000"/>
            <objectAnimator
                android:propertyName="alpha"
                android:valueType="floatType"
                android:valueFrom="0.2"
                android:valueTo="1"
                android:duration="5000"/>
    
        </set>
    
        <!--顺序执行-->
        <set android:ordering="sequentially">
            <objectAnimator
                android:propertyName="translationX"
                android:valueType="floatType"
                android:valueFrom="0"
                android:valueTo="-300"
                android:duration="1000"/>
            <objectAnimator
                android:propertyName="translationY"
                android:valueType="floatType"
                android:valueFrom="0"
                android:valueTo="600"
                android:duration="1000"/>
            <objectAnimator
                android:propertyName="translationX"
                android:valueType="floatType"
                android:valueFrom="-300"
                android:valueTo="300"
                android:duration="1000"/>
            <objectAnimator
                android:propertyName="translationY"
                android:valueType="floatType"
                android:valueFrom="600"
                android:valueTo="0"
                android:duration="1000"/>
            <objectAnimator
                android:propertyName="translationX"
                android:valueType="floatType"
                android:valueFrom="300"
                android:valueTo="0"
                android:duration="1000"/>
        </set>
    </set>
    
    public void animatorSet(View view) {
        // 加载动画 
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.set);
        // 作用对象
        animator.setTarget(iv);
        // 开始
        animator.start();
    }
    

    效果

    7、动画监听

    • ViewPropertyAnimator#setUpdateListener() 和 ValueAnimator#addUpdateListener()

      参数都是ValueAnimator.AnimatorUpdateListener,上面也示例过了,只是其中参数都是ValueAnimator#getAnimatedValue()不同:

      ViewPropertyAnimator#setUpdateListener返回的是当前时刻完成度
      ValueAnimator#addUpdateListener返回的是当前时刻的具体属性值

    • ViewPropertyAnimator#setListener() 和 ValueAnimator#addListener()
      参数都是Animator.AnimatorListener,如下:

     animator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            // 动画开始时被调用
        }
    
        @Override
        public void onAnimationEnd(Animator animation) {
            // 动画结束、取消时被调用
        }
    
        @Override
        public void onAnimationCancel(Animator animation) {
            // 动画取消时调用,先调用cancel,再调用end
        }
    
        @Override
        public void onAnimationRepeat(Animator animation) {
            // 当动画通过 setRepeatMode() / setRepeatCount() 或 repeat() 方法重复执行时,这个方法被调用
    
            // ViewPropertyAnimator 不支持重复,所以这个方法对 ViewPropertyAnimator 无效
        }
    });
    

    四、Interpolator

    插值器,就是速度设置器

    java xml 效果
    AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 默认,先加速再减速
    AccelerateInterpolator @android:anim/accelerate_interpolator 持续加速
    DecelerateInterpolator @android:anim/decelerate_interpolator 持续减速
    AnticipateInterpolator @android:anim/anticipate_interpolator 蓄力效果,先回拉再加速动画
    OvershootInterpolator @android:anim/overshoot_interpolator 回弹效果,超出终点后再回终点
    AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 蓄力+回弹
    BounceInterpolator @android:anim/bounce_interpolator 结束时有弹跳效果
    CycleInterpolator @android:anim/cycle_interpolator 回弹效果,不同于上面的一点回弹,像荡秋千一样,回弹次数由构造中传入值决定
    LinearInterpolator @android:anim/linear_interpolator 匀速

    个人总结,水平有限,如果有错误,希望大家能给留言指正!如果对您有所帮助,可以帮忙点个赞!如果转载,希望可以标明文章出处!最后,非常感谢您的阅读!

    展开全文
  • Android各种动画效果

    千次阅读 2016-06-08 15:17:33
    现在开发的软件是越来越炫酷了,各种各样的动画都会出现,吸引用户的眼球。客户的需求才是我们做技术能力提升的条件,这就使我们对动画实现要更加的熟练包括一些自定义控件快速的运用和编写。最近,我也搜集了很多...

    现在开发的软件是越来越炫酷了,各种各样的动画都会出现,吸引用户的眼球。客户的需求才是我们做技术能力提升的条件,这就使我们对动画实现要更加的熟练包括一些自定义控件快速的运用和编写。最近,我也搜集了很多关于动画的样式,供大家有需求的可以查看,每一个样式我都会把demo链接。我发现我的语言组织能力越来越差了,可能是很久没有写过文章,或许是我们做技术的会渐渐的丧失这方面能力,毕竟说话的时间较少全部都用代码展示了。呵呵!我觉得写博客能提升这方面的能力,坚持写博客不仅会让我们积累技术方面的知识,也会慢慢培养一种习惯。语言表达得不怎么好,好吧!言归正传,看图:


    这个风车旋转的效果是仿墨迹天气实现的效果,主要是运用到了SurfaceView,和实现了SurfaceHolder.Callback接口,具体的不多说,上链接demo:http://download.csdn.net/detail/qq_32365567/9544473。


    这种烟花效果运用的很多自定义的视图以及烟花爆炸的每一个小点的组成,再加上动画的组成和声音的注入,绝对会让app立即生动起来。下载链接:http://download.csdn.net/detail/qq_32365567/9544598


    这个主要是关于activity之间的切换,最主要的还是android基本2大动画之间的组成,多运用就会变得熟练。下载链接demo:http://download.csdn.net/detail/qq_32365567/9543969


    这是一个关于窗帘似的效果和弹出登录的效果,窗帘的实现是自定义的布局和实现触摸接口,以及关于屏幕的分辨率,登录的效果与窗帘实现效果类似。下载链接:http://download.csdn.net/detail/qq_32365567/9543980


    这种类似雷达的搜索主要用的是自定义的RelativeLayout布局,再加上一些动画实现的效果。下载链接demo:http://download.csdn.net/detail/qq_32365567/9544088

    这种和黑客帝国的字符雨很像吧!看着简直就是很牛逼,那这个又是怎么实现的呢?是继承的GLSurfaceView,而这个GLSurfaceView类也是继承的SurfaceView,归根结底还是用的SurfaceView方法实现。再加上一些动画,这个实现起来比较复杂,直接上代码吧!http://download.csdn.net/detail/qq_32365567/9544504


    这个就是钟表的摇摆,也可以用成荡秋千的形式,运用到的是类继承的Animation,加上吊坠的偏移程度,动画的时间和重播次数等。下载链接:http://download.csdn.net/detail/qq_32365567/9543988


    这个是自定义的视图,结合到线程的播放不同的图片,以及加上的传感器的运用,这里是用音频的采样率监听的事件,下载demo:http://download.csdn.net/detail/qq_32365567/9544093


    这种可能在app上会常用了,进入程序时等。其实也就是一个自定义的TextView设置样式,和一些jar包的封装,下载链接:http://download.csdn.net/detail/qq_32365567/9544499


    火苗的是实现效果也是运用到了SurfaceView,下载demo:http://download.csdn.net/detail/qq_32365567/9544590


    这是仿58同城的加载类似效果,自定义的视图和自定义的线性布局,下载链接demo:http://download.csdn.net/detail/qq_32365567/9544608

    好了,以上是我整理的一些动画样式,有些可以自己改动就可用到自己的样式。我把这些动画放上去,是为了以后可以直接到这里来找,这也是写博客的一个原因,把好的东西整理的东西放上去,减少以后到处找的麻烦。希望也能帮到大家想要的东西。

    展开全文
  • Android动画大合集

    千次阅读 2019-03-04 11:04:23
      android中动画实现方式繁多,在项目中也经常用到动画,网上有很多人也都进行了一些总结,但是感觉还是零零散散,自己总结一下才能加深印象,以后有时间了,也可以从各个分类里进一步去补充完善。 如果喜欢看...

      android中的动画实现方式繁多,在项目中也经常用到动画,网上有很多人也都进行了一些总结,但是感觉还是零零散散,自己总结一下才能加深印象,以后有时间了,也可以从各个分类里进一步去补充完善。

    如果喜欢看Google官方英文文档的,可以直接移步Animations and Transitions

    一、View Animation

    1、Tween Animation 补间动画

      这类动画比较简单,一般就是平移、缩放、旋转、透明度,或者其组合,可以用代码或者xml文件的形式,推荐使用xml文件形式,因为可以复用。

      四个动画效果实现类:TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation、AnimationSet,对应的的XML标签为translate、 scale、 rotate、alpha、set,其中set里还可以放set,然后放在放置在res/anim/目录下,关于详细使用这里不再做介绍。

    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@[package:]anim/interpolator_resource"
        android:shareInterpolator=["true" | "false"] >
        <alpha
            android:fromAlpha="float"
            android:toAlpha="float" />
        <scale
            android:fromXScale="float"
            android:toXScale="float"
            android:fromYScale="float"
            android:toYScale="float"
            android:pivotX="float"
            android:pivotY="float" />
        <translate
            android:fromXDelta="float"
            android:toXDelta="float"
            android:fromYDelta="float"
            android:toYDelta="float" />
        <rotate
            android:fromDegrees="float"
            android:toDegrees="float"
            android:pivotX="float"
            android:pivotY="float" />
        <set>
            ...
        </set>
    </set>
    

    代码中使用:

    ImageView image = (ImageView) findViewById(R.id.image);
    Animation hyperspaceJump = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
    image.startAnimation(hyperspaceJump);
    
    AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
        R.animator.property_animator);
    set.setTarget(myObject);
    set.start();
    

    参考网上的一个停止补间动画的正确姿势:

    public void stopAnimation(View v) {
        v.clearAnimation();
        if (canCancelAnimation()) {
           v.animate().cancel();    
        }    
        animation.setAnimationListener(null);    
        v.setAnimation(null);
    }
    
    /**
     * Returns true if the API level supports canceling existing animations via the 
     * ViewPropertyAnimator, and false if it does not 
     * @return true if the API level supports canceling existing animations via the 
     * ViewPropertyAnimator, and false if it does not 
     */
    public static boolean canCancelAnimation() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    }
    

    2、Frame Animation(Drawable Animation)逐帧动画

      如果要做很炫酷的下来刷新或者loading动画,可以考虑使用Airbnb开源的动画框架Lottie
      简单讲就是把几个静态的图片快速播放形成动画,可以使用AnimationDrawable,官方推荐使用XML文件,放在res/drawable/路径下,
    代码如下所示:

    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="true">
        <item android:drawable="@drawable/thrust1" android:duration="200" />
        <item android:drawable="@drawable/thrust2" android:duration="200" />
        <item android:drawable="@drawable/thrust3" android:duration="200" />
    </animation-list>
    

      android:oneshot="true"表示只执行一次动画,false表示无限循环,

    ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
    rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
    rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
    rocketImage.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
            rocketAnimation.start();
          }
      });
    

      注意调用AnimationDrawable的start方法时,不能在Activity的onCreat里,因为这时AnimationDrawable还没有完全依附到window上,如果一开始就想执行动画,可以放在onStart方法里

      还有一种矢量动画AnimatedVectorDrawable, 感兴趣的可以查看这里
    https://developer.android.google.cn/guide/topics/graphics/drawable-animation

    二、Property Animation 属性动画

      属性动画,顾名思义,只要对象里有属性的set和get方法,就可以利用这个属性去做动画。
      上面介绍的View Animation都是对View进行的操作,准确的说,是改变View的绘制,并没有改变View对象本身的属性值,且只有一些基本的动画效果,不能改变background color等,属性动画可以对任何对象进行改变(我好像还没遇到这种场景)。官网介绍,相比Property Animation,View Animation启动所需的时间少,要写的代码也少,所以,如果能用视图动画搞定的动画,就没有必要使用属性动画了。

      在android.view.animation包里定义的差值器interpolators可以用在属性动画中。

      属性动画使用Animator的子类,通常是ValueAnimator和ObjectAnimator ,ValueAnimator只能计算属性值的变化,可以设置监听然后自己处理相关逻辑;ObjectAnimator可以对对象的属性值计算后,直接应用于对象的相应属性。

    1、ValueAnimator

    ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
    animation.setDuration(1000);
    animation.start();
    

      或者对自定义的类型进行动画:

    ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
    fadeAnim.setDuration(250);
    fadeAnim.addListener(new AnimatorListenerAdapter() {
    public void onAnimationEnd(Animator animation) {
        balls.remove(((ObjectAnimator)animation).getTarget());
    }
    fadeAnim.start();
    
    animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator updatedAnimation) {
            // You can use the animated value in a property that uses the
            // same type as the animation. In this case, you can use the
            // float value in the translationX property.
            float animatedValue = (float)updatedAnimation.getAnimatedValue();
            textView.setTranslationX(animatedValue);
        }
    });
    

    2、ValueAnimator

      ObjectAnimator和AnimatorSet的使用:

    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
    
    AnimatorSet bouncer = new AnimatorSet();
    bouncer.play(bounceAnim).before(squashAnim1);
    bouncer.play(squashAnim1).with(squashAnim2);
    bouncer.play(squashAnim1).with(stretchAnim1);
    bouncer.play(squashAnim1).with(stretchAnim2);
    bouncer.play(bounceBackAnim).after(stretchAnim2);
    ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
    fadeAnim.setDuration(250);
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.play(bouncer).before(fadeAnim);
    animatorSet.start();
    

      在一次需要修改多个属性值时,除了可以使用AnimatorSet, 还可以使用语法更简洁的ViewPropertyAnimator,同时ViewPropertyAnimator也更高效,代码对比如下:

       Multiple ObjectAnimator objects

    ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
    ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
    AnimatorSet animSetXY = new AnimatorSet();
    animSetXY.playTogether(animX, animY);
    animSetXY.start();
    

       One ObjectAnimator

    PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
    PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
    ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
    

      ViewPropertyAnimator

    myView.animate().x(50f).y(100f);
    

      关于ViewPropertyAnimator的更多介绍,可以查看官网介绍 blog post.

    三、Spring Animation 弹性动画

      这类动画是模仿现实中的弹力效果,每一帧都是通过计算相应的弹力=得到,可以设置弹性动画的阻尼率和刚度来达到不同的弹性效果。

    添加依赖

    dependencies {
          implementation 'com.android.support:support-dynamic-animation:27.1.1'
      }
    

    以下是一个应用了链式弹性动画Chained spring的效果图,
    这里写图片描述

      弹性动画使用SpringAnimation类,具体可参考官网介绍:Animate movement using spring physics 或者 Android中弹簧动画的那些事 - SpringAnimation

    四、Fling Animation

      Fling Animation类似于列表ListView在快速滚动时到最后列表停止滚动的效果。

    这里写图片描述

      Fling Animation使用FlingAnimation类,具体可参考官网介绍:Move views using a fling animation

    五、 Layout Animation 布局动画

      当改变一个布局的元素时,android提供了一种预加载动画,使用默认的布局动画,只需要对一个layout设置一个属性,如下所示:

    <LinearLayout android:id="@+id/container"
        android:animateLayoutChanges="true"
        ...
    />
    

    当对这个LinearLayout中添加、删除或者更新子View时,这些子View就会自动添加上默认的动画效果。

    private ViewGroup mContainerView;
    ...
    private void addItem() {
        View newView;
        ...
        mContainerView.addView(newView, 0);
    }
    

    除了默认的布局动画,也可以自定义动画,并使用setAnimator方法设置给ViewGroup,以后有时间可以仔细研究一下,

    public void setAnimator (int transitionType, 
                    Animator animator)
    

    六、 Layout Transition 布局转场动画

      转场动画可以在两个布局之间,产生动画效果,步骤如下:

      1.根据其实布局和结束布局,创建Scene对象,
      2.创建一个Transition对象,用来定义所需的动画类型
      3.调用TransitionManager.go(),然后系统就在两个布局之间产生动画

    这里写图片描述

      更多内容请参考 Animate layout changes using a transition
    Create a custom transition animation

    七、 Activity transition Activity转场动画

      从Android5.0(API21)开始,可以使用 Activity transition,所以要注意低版本的效果适配。

    1、使用transition启动一个Activity

      当给一个Activity指定了退出的转场动画,在启动一个新的Activity时,将调用动画效果,如果新启动的Activity也设置了进入的转场动画,那么在启动时,也会产生相应的动画,要禁用动画效果时,传一个空的bundle

      使用Activity转场动画,要在使用的theme里,将android:windowActivityTransitions设置为true

    <style name="BaseAppTheme" parent="android:Theme.Material">
      <!-- enable window content transitions -->
      <item name="android:windowActivityTransitions">true</item>
    
      <!-- specify enter and exit transitions -->
      <item name="android:windowEnterTransition">@transition/explode</item>
      <item name="android:windowExitTransition">@transition/explode</item>
    
      <!-- specify shared element transitions -->
      <item name="android:windowSharedElementEnterTransition">
        @transition/change_image_transform</item>
      <item name="android:windowSharedElementExitTransition">
        @transition/change_image_transform</item>
    </style>
    

      然后在代码中

    // inside your activity (if you did not enable transitions in your theme)
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    
    // set an exit transition
    getWindow().setExitTransition(new Explode());
    
    startActivity(intent,
                  ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    

    2、shared element共享元素动画

      可以共享一个或者多个元素,简要代码如下,

    // get the element that receives the click event
    final View imgContainerView = findViewById(R.id.img_container);
    
    // get the common element for the transition in this activity
    final View androidRobotView = findViewById(R.id.image_small);
    
    // define a click listener
    imgContainerView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(this, Activity2.class);
            // create the transition animation - the images in the layouts
            // of both activities are defined with android:transitionName="robot"
            ActivityOptions options = ActivityOptions
                .makeSceneTransitionAnimation(this, androidRobotView, "robot");
            // start the new activity
            startActivity(intent, options.toBundle());
        }
    });
    

      多个共享元素时:

    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
            Pair.create(view1, "agreedName1"),
            Pair.create(view2, "agreedName2"));
    

    推荐博文:
    【Transition】Android炫酷的Activity切换效果,共享元素

    八、用ConstraintLayout和ConstraintSet实现动画

      这个放在最后写,因为感觉最牛逼啊,其实和上面介绍到的Layout Transition 布局转场动画很相似,先是用ConstraintLayout写两个布局文件,然后利用TransitionManager调用beginDel ayedTransition()启动一个延时转场动画就行,且ConstraintLayout支持到API 9,TransitionManager支持到API 14,所以多使用ConstraintSet来做动画,兼容性不用担心,除了在两个布局里转场,在一个布局内改变某个View的属性(如边距),其余的View也会自动产生平滑的动画效果,其他什么动画相关代码都不用写,,,,,惊不惊喜!

    使用ConstraintLayout制作漂亮的动画

    ConstraintLayout 炫酷的动画

      利用给Transition设置相应的差值器Interpolator,就能产生更加fashion的效果,感兴趣的同学可以观看以下视频教程:

      用四行代码来实现复杂动画 | 中文教学视频

    //2018.12.23 更新

    九、用MotionLayout实现动画

    MotionLayout 因何而生?
    Android 框架已经提供了好几种在 App 里添加动画的方式:

    Animated Vector Drawable
    Property Animation framework
    LayoutTransition animations
    Layout transitions with TransitionManager
    CoordinatorLayout

    下面将揭示 MotionLayout 和上面这些已有方案的不同。

    暂时没事时间研究,先把网址贴一下:

    『译』ConstrainLayout 2.0 之 MotionLayout(Part1.1)

    【翻译】MotionLayout实现折叠工具栏(Part 1)
    【翻译】MotionLayout实现折叠工具栏(Part 2)

    展开全文
  • 本文总结了矢量图形和矢量动画的使用方法。
  • Android动画分为了三种, 分别是 帧动画、View动画、属性动画。 1、帧动画动画就是顺序播放一组预先定义好的图片,就类似于我们观看视频,就是一张一张的图片连续播放。 帧动画的使用很简单,总共就两个步骤...
  • 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(frame-by-frame animation)和补间动画(tweened animation)。逐帧动画的工作原理很...
  • Android 三种动画详解

    千次阅读 2017-03-02 10:13:18
    不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android动画,所以今天来一发Android应用的各种Animation大集合。英文厉害的请直接移步参考Android Developer。 Android系统...
  • Android三种动画实现原理及使用

    万次阅读 2018-06-07 21:06:06
    Android动画目前分为三种:Frame Animation 帧动画,通过顺序播放一系列图像从而产生动画效果,。图片过多时容易造成OOM(Out Of Memory内存用完)异常。Tween Animation 补间动画(又叫view动画),是通过对场景里...
  • Android动画(1)

    2018-05-13 13:17:56
    详细的动画使用攻略前言动画的使用 是 Android 开发常用的知识可是动画的种类繁多、使用复杂,每当需要 采用自定义动画 实现 复杂的动画效果时,很多开发者就显得束手无策本文将献上一份Android动画的全面介绍...
  • 安卓动画

    2019-12-14 10:42:04
    Android的三种动画,即: •View Animation(视图动画) •Drawable Animation(帧动画) •Property Animation(属性动画) Drawable Animation(帧动画): 2.1帧动画概述 帧动画是顺序播放一组预先定义好的...
  • Android动画效果集合开源APP(BaseAnimation1.3)程序源码

    千次下载 热门讨论 2020-07-27 23:31:05
    BaseAnimation1.3版本增加如下动画 1.Splash增加2个动画 2.高仿动画效果增加10个 3.ListView集合增加15个 4.自定义控件集合增加17个 5.页面滑动增加4个 共增加48个动画效果 下载app源码的朋友需要把 BAnim ...
  • Android 动画:手把手教你使用 补间动画 (视图动画)

    万次阅读 多人点赞 2019-04-27 10:53:45
    本文将详细介绍 Android 动画中 补间动画的原理 & 使用 学习Android 动画最好先了解:自定义View的原理,请参考我写的文章: (1)自定义View基础 - 最易懂的自定义View原理系列 (2)自定义View Meas
  • android 动画面试

    千次阅读 2019-03-01 10:53:14
    动画详解 ... 三种动 1.视图动画(view Animation) 2.帧动画() ...3.属性动画 ...插值器(Interpolator)与估值器(TypeEvaluator...通过动画可以实现一些比较绚丽的效果,但是在使用过程,也需要注意一些事情,主...
  • Android 动画监听事件

    千次阅读 2015-04-02 09:23:19
    public class GuideActivity extends Activity { // 显示图片的ImageView组件 private ImageView guidePicture; ...// 要展示的一组图片资源...// 每张展示图片要执行的一组动画效果 private Animation[] animation
  • 最近想自定义一个ViewGroup来实现一些动画,我目前是这样写的,就是用两个数组,一个数组来保存所有的子View ,还有一个数组来保存子view的一些位置参数,然后当动画开始的时候,就不停的改变参数数组里面的值,然后...
  • Android动画之视图动画和属性动画

    千次阅读 2016-05-13 17:16:25
    View Animation视图动画Android最基础的动画,在API 1就已经加入,不需考虑兼容性,但由于其动画只是作用于视图上,而不会由该控件的属性,所以有很多的局限性。视图动画的基类是Animation其下
  • Android中动画效果

    千次阅读 2016-08-28 09:59:47
    动画
  • 这里把布局动画和Activity切换动画都归类为特殊场景的动画使用,因此放在一起来介绍它们的使用技巧。所谓布局动画即在ViewGroup布局发生改变(如addView,removeView...)时提供的一个过渡动画。根据布局动画效果的...
  • Android 动画框架的基本原理

    千次阅读 2016-12-18 13:41:03
    Android 平台提供了一套完整的动画框架,使得开发者可以用它来开发各种动画效果,本文将向读者阐述 Android动画框架是如何实现的。 任何一个框架都有其优势和局限性,只有明白了其实现原理,开发者才能知道哪些...
1 2 3 4 5 ... 20
收藏数 177,113
精华内容 70,845
关键字:

android动画