Android的三大动画

一、补间动画

补间动画的作用对象是View,支持四种动画效果,分别是平移动画,缩放动画,旋转动画,透明度动画。视图动画既可以是单个动画,也可以有一系列动画组成。补间动画的四种分别对应Animation的四个子类(TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation),除了以上四个子类它还有一个AnimationSet类,对应xml标签为,它是一个容器,可以包含若干个动画,并且内部也可以继续嵌套集合

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <!--平移动画标签,数值、百分数、百分数p,例如50表示以当前View左上角坐标加50px为初始点、50%表
    示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高
    的50%做为初始点-->
    <translate
        android:duration="4000"
        android:fromXDelta="0%p"
        android:fromYDelta="0%p"
        android:toXDelta="20%p"
        android:toYDelta="20%p" />
    <!--缩放动画标签,其中pivotX为缩放起点X轴坐标-->
    <scale
        android:duration="4000"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0.2"
        android:toYScale="0.2" />
    <!--旋转动画标签,fromDegrees是旋转开始角度,正代表顺时针度数,负代表逆时针度数-->
    <rotate
        android:duration="4000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
    <!--透明度动画标签,fromAlpha为动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明)-->
    <alpha
        android:duration="4000"
        android:fromAlpha="1.0"
        android:toAlpha="0.2" />
</set>

比如我们对TextView设置动画,使其点击后执行动画

txt.setOnClickListener {
            it.startAnimation(AnimationUtils.loadAnimation(this, R.anim.animview))
        }
Animation类的方法 作用
reset() 重置Animation的初始化
cancel() 取消Animation动画
start() 开始Animation动画
setAnimationListener() 给当前Animation设置动画监听
hasStarted() 判断当前Animation是否开始
hasEnded() 判断当前Animation是否结束
clearAnimation() 取消当View在执行的Animation动画

补间动画执行之后并未改变View的真实布局属性值。例如我们在Activity中有一个 Button在屏幕上方,我们设置了平移动画移动到屏幕下方然后保持动画最后执行状态呆在屏幕下方,这时如果点击屏幕下方动画执行之后的Button是没 有任何反应的,而点击原来屏幕上方没有Button的地方却响应的是点击Button的事件。在进行动画的时候,尽量使用dp,因为px会导致适配问题

插值器
插值器定义了动画的变化率,能帮助我们实现非线性改变的动画

xml 描述
@android:anim/accelerate_decelerate_interpolator 动画始末速率较慢,中间加速
@android:anim/accelerate_interpolator 动画开始速率较慢,之后慢慢加速
@android:anim/bounce_interpolator 动画结束时弹起
@android:anim/decelerate_interpolator 动画开始快然后慢
@android:anim/overshoot_interpolator 向前弹出一定值之后回到原来位置

估值器
估值器的作用是根据开始值、结束值、开始结束之间的一个比例来计算出最终的值
系统默认提供了3种估值器:
(1)IntEvaluator整型估值器,值的类型为整型
(2)FloatEvaluator浮点型估值器,值的类型为浮点型
(3)ArgbEvaluator,值的类型为ARGB值,可以用来计算颜色值

帧动画

帧动画是顺序播放一组预先定义好的图片,不同于补间动画,系统提供了另外一个类AnimationDrawable来使用帧动画
在drawable文件夹下创建xml文件,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
<!--oneshot为true代表只执行一次,false循环执行-->
    <item android:drawable="@drawable/text_bg" android:duration="180"/>
    <item android:drawable="@drawable/text_bg2" android:duration="180"/>
    <item android:drawable="@drawable/text_bg3" android:duration="180"/>
    <item android:drawable="@drawable/text_bg4" android:duration="180"/>
</animation-list>

执行动画,如下所示:

 txt.setBackgroundResource(R.drawable.anim_zhen)
        txt.setOnClickListener {
            val animationDrawable = it.background as AnimationDrawable
            animationDrawable.start()
        }

属性动画

出现的原因
在属性动画出现以前,Android主要有两种动画,帧动画(Frame Animation)和补间动画(Tween Animation),这两种动画统称为视图动画。帧动画是通过逐帧播放图片来实现动画效果,补间动画虽然提供了旋转、缩放、位移、透明度的动画效果,却有不可忽视的三大缺陷:
(1)作用对象有限,只能作用于View及其子类
(2)动画种类有限,只有旋转、缩放、位移、透明度4种动画
(3)只改变了View的显示效果,没有真正改变View的属性。例如:对View作位移的补间动画后,View虽然显示改变,但是响应区域却还在原来的位置
原理
属性动画通过在预设的规则下不断地改变值,并将值设置给作用对象的属性,从而达到动画效果。这个规则可以由我们定制,其中有两个重要的工具,可以帮助我们定制值的变化规则,一个是插值器(Interpolator),一个是估值器(TypeEvaluator)

插值器定义了动画的变化率,能帮助我们实现非线性改变的动画,如加速变化的AccelerateInterpolator
估值器的作用是计算出动画对应的最终的属性值。系统默认提供了3种估值器:
(1)IntEvaluator整型估值器,值的类型为整型
(2)FloatEvaluator浮点型估值器,值的类型为浮点型
(3)ArgbEvaluator,值的类型为ARGB值,可以用来计算颜色值

属性动画的使用
属性动画主要通过两个类来使用,ValueAnimator和ObjectAnimator,这两个的区别主要是:ValueAnimator只是计算值,赋值给对象属性需要我们手动监听值的变化来进行;ObjectAnimator则对赋值属性这一步封装进了内部,也就是自动赋值
ValueAnimator的使用
在res目录里创建animator目录,之后创建Animator resources file

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:repeatCount="1"
    android:repeatMode="reverse"
    android:valueFrom="30"
    android:valueTo="200"
    android:valueType="intType" />

ValueAnimator提供了回调以监听动画值,我们可以在此回调中拿到属性值并手动赋值给对象属性,从而达到效果,需要注意的是,对象是View的时候,有时需要我们在赋值属性后调用View.invalidate()或者View.requestLayout()方法来刷新界面实现视觉效果

        val valueAnimator = AnimatorInflater.loadAnimator(this, R.animator.animator_hi) as ValueAnimator
        //设置动画持续时间,以毫秒为单位
        valueAnimator.duration = 2000
        //设置插值器
        valueAnimator.interpolator = DecelerateInterpolator()
        //设置动画重复模式,RESTART表示动画正序重复,REVERSE代表倒序重复
        valueAnimator.repeatMode = ValueAnimator.REVERSE
        //设置重复次数,ValueAnimator.INFINITE表示无限重复
        valueAnimator.repeatCount = 10
        //设置动画延迟播放的时间
        valueAnimator.startDelay = 1000
        valueAnimator.addUpdateListener {
            val value = it.animatedValue.toString()
            txt.textSize = value.toFloat()
        }
        valueAnimator.start()

ObjectAnimator的使用
与ValueAnimator对比
(1)ObjectAnimator是ValueAnimator的子类
(2)ValueAnimator只是对值进行平滑的动画过渡;ObjectAnimator直接对任意对象的任意属性进行动画操作
(3)ValueAnimator需要我们为对象属性手动赋值;ObjectAnimator会为对象属性自动赋值

(1) ValueAnimator.ofInt(int… values):值的类型是int,会默认使用整形估值器
(2) ValueAnimator.ofFloat(float… values):值的类型是float,会默认使用浮点型估值器
(3) ValueAnimator.ofArgb(int… values):值的类型是代表颜色的32位的int,会默认使用ArgbEvaluator估值器
(4) ValueAnimator.ofObject(TypeEvaluator evaluator,Object… values):对应值的类型是Object,这种方式需要显式传入估值器,因为对于Object类型没有系统提供的估值器,也不可能提供估值器,因为对于不同的对象其计算方式不同

        /*
          参数解释:
          target:ObjectAnimator作用的对象
          propertyName:属性名
          values:过渡值(开始值、结束值)
        */
        val objectAnimator = ObjectAnimator.ofFloat(txt, "textSize", 10f, 100f)
        objectAnimator.duration = 3000
        objectAnimator.repeatCount = Animation.INFINITE
        objectAnimator.repeatMode = ValueAnimator.REVERSE
        objectAnimator.start()

组合动画AnimatorSet
AnimatorSet用于把很多动画按照一定顺序组合起来播放,AnimatorSet采用了构造器模式来组合动画

    val objectAnimator = ObjectAnimator.ofFloat(txt, "textSize", 10f, 100f)
        val objectAnimator1 = ObjectAnimator.ofFloat(txt, "rotation", 0f, 360f)
        objectAnimator.repeatCount = Animation.INFINITE
        objectAnimator.repeatMode = ValueAnimator.REVERSE
        objectAnimator1.repeatCount = Animation.INFINITE
        objectAnimator1.repeatMode = ValueAnimator.REVERSE
        val animatorSet = AnimatorSet()
        animatorSet.duration = 3000
        animatorSet.play(objectAnimator).with(objectAnimator1)

动画的监听

 objectAnimator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationStart(animation: Animator?) {

            }
        })
        objectAnimator.addPauseListener(object : AnimatorListenerAdapter() {
            override fun onAnimationPause(animation: Animator?) {

            }
        })

猜你喜欢

转载自blog.csdn.net/qq_45485851/article/details/108448631
今日推荐