美文网首页
Android 动画总结(5) - 属性动画

Android 动画总结(5) - 属性动画

作者: 三流之路 | 来源:发表于2018-04-01 18:26 被阅读0次

    Android 动画总结(1) - 概述
    Android 动画总结(2) - 帧动画
    Android 动画总结(3) - 补间动画
    Android 动画总结(4) - 插值器
    Android 动画总结(6) - 估值器
    Android 动画总结(7) - ViewGroup 子元素间的动画
    Android 动画总结(8) - Activity 转场动画
    Android 动画总结(9) - 过渡动画


    属性动画改变属性值,所以几乎可以对任何对象执行动画,而不仅仅是 View,比起补间动画,适用范围更广。

    包括 ValueAnimator、ObjectAnimator 和 AnimatorSet:

    • ValueAnimator 只是计算动画各帧的属性值,将这些属性值如何设置给相应的对象需要开发者自己实现,本身只是对值计算,并不设置具体对象。
    • ObjectAnimator 是 ValueAnimator 的子类,将 ValueAnimator 计算后的属性设置给具体的对象。
    • AnimatorSet 组合多个 Animator,并指定这些 Animator 的播放顺序。

    有几个静态方法:ofIntofArgbofPropertyValuesHolderofObject

    xml 方式

    res/animator 目录下创建 animator_set.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:ordering="sequentially" >
        <objectAnimator
            android:propertyName="scaleX"
            android:duration="200"
            android:valueFrom="1"
            android:valueTo="0.4"
            android:valueType="floatType" />
    
        <animator
            android:duration="200"
            android:valueFrom="2"
            android:valueTo="5"
            android:repeatCount="2"
            android:repeatMode="reverse" />
        
        <set>
            <objectAnimator
                android:propertyName="x"
                android:duration="100"
                android:valueTo="500"
                android:valueType="intType"
                android:startOffset="100" />
            <objectAnimator
                android:propertyName="backgroundColor"
                android:duration="200"
                android:valueFrom="#FF0000"
                android:valueTo="#00FFFF"
                android:valueType="floatType" />
            
        </set>
    </set>
    
    val animator = AnimatorInflater.loadAnimator(ctx, R.animator.animator_set)
    animator.setTarget(imageView) // 将动画设置到某个对象上
    animator.start()
    

    代码方式

    val childSet = AnimatorSet()
    childSet.playSequentially(
            ObjectAnimator.ofFloat(myObject, "rotationX", 0f, 360f),
            ObjectAnimator.ofFloat(myObject, "rotationY", 0f, 360f),
            ObjectAnimator.ofFloat(myObject, "alpha", 1f, 0.25f, 1f).setDuration(200)
    )
    
    val set = AnimatorSet()
    set.playTogether(
    
            ObjectAnimator.ofFloat(myObject, "rotation", 0f, 360f),
            ObjectAnimator.ofFloat(myObject, "translationX", 0f, 90f),
            ObjectAnimator.ofFloat(myObject, "translationY", 0f, 90f),
            ObjectAnimator.ofFloat(myObject, "scaleX", 1f, 1.5f),
            ObjectAnimator.ofFloat(myObject, "scaleY", 1f, 1.5f)
    )
    set.setDuration(5000).start()
    

    属性

    和补间动画一样的属性有:

    • android:duration

    • android:interpolator

    • android:repeatCount -1 表示无限循环

    • android:repeatMode

    • set

      • android:ordering
        • sequentially 顺序播放
        • together 同时播放,默认值
    • animator ValueAnimator 用这个标签

      • android:valueTo 必需
      • android:valueFrom 必需
      • android:valueType
    • objectAnimator

      • android:propertyName 必需,所作用的属性名
      • android:valueTo float/int/color,必需,动画结束时的属性值
      • android:valueFrom 动画开始时的属性值
      • android:valueType intType/floatType(默认),如果 value 是颜色值,属性动画内部已经处理了 color

    监听器

    public static interface AnimatorListener {
        default void onAnimationStart(Animator animation, boolean isReverse) {
            onAnimationStart(animation);
        }
        default void onAnimationEnd(Animator animation, boolean isReverse) {
            onAnimationEnd(animation);
        }
        void onAnimationStart(Animator animation);
        void onAnimationEnd(Animator animation);
        void onAnimationCancel(Animator animation);
        void onAnimationRepeat(Animator animation);
    }
    
    public static interface AnimatorPauseListener {
        void onAnimationPause(Animator animation);
        void onAnimationResume(Animator animation);
    }
    
    
    public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener, Animator.AnimatorPauseListener {
        @Override
        public void onAnimationCancel(Animator animation) {
        }
        @Override
        public void onAnimationEnd(Animator animation) {
        }
        @Override
        public void onAnimationRepeat(Animator animation) {
        }
        @Override
        public void onAnimationStart(Animator animation) {
        }
        @Override
        public void onAnimationPause(Animator animation) {
        }
        @Override
        public void onAnimationResume(Animator animation) {
        }
    }
    
    public static interface AnimatorUpdateListener {
        void onAnimationUpdate(ValueAnimator animation);
    }
    

    其中 AnimatorListenerAdapter 是抽象类,空实现了 AnimatorListenerAnimatorPauseListener,这样使用时可以选择重写哪个方法。AnimatorUpdateListener 播放一帧就回调一次。

    colorAnimator.addListener(object : Animator.AnimatorListener {
        override fun onAnimationRepeat(animation: Animator?) {}
        override fun onAnimationEnd(animation: Animator?) {}
        override fun onAnimationCancel(animation: Animator?) {}
        override fun onAnimationStart(animation: Animator?) {}
    })
    colorAnimator.addPauseListener(object : Animator.AnimatorPauseListener {
        override fun onAnimationPause(animation: Animator?) {}
        override fun onAnimationResume(animation: Animator?) {}
    })
    colorAnimator.addListener(object : AnimatorListenerAdapter() {
        // 只需要这一个,那就重写这一个
        override fun onAnimationEnd(animation: Animator?) {}
    })
    colorAnimator.addUpdateListener {
        it.animatedValue // 拿到值
    }
    

    对任意属性做动画

    动画生效的条件:

    1. 这个属性要有对应的 setter 方法,如果没有提高初始值,还需要 getter 方法。
    2. setter 方法设置后能够真的改变这个属性值

    如果不满足条件的解决方法

    1. 直接加上 getter/setter 方法去改变属性
    2. 使用装饰模式包装个类,提供 getter/setter 方法,方法内部进行转变使得能够设置到属性上
    3. 使用 ValueAnimator,只计算,然后加 AnimatorUpdateListener,在监听里自己去改变效果

    ViewPropertyAnimator

    ViewPropertyAnimator 提供了一种可以使多个属性同时做动画的简单方法,而且它在内部只使用一个 Animator。当它计算完这些属性的值之后,直接把那些值赋给目标 View 并 invalidate 那个对象,而它完成这些的方式比普通的 ObjectAnimator 更加高效。

    myView.animate().alpha(0); // 淡出
    myView.animate().x(500).y(500); // 移动这个 View 的 x 值和 y 值到 (500, 500) 这个位置
    
    view.animate().alpha(0.5f).rotation(360f).scaleX(1.5f).scaleY(1.5f)
        .translationX(50f).translationY(50f).duration = 1000
    

    方法:

    • alpha(float value) - 设置透明度,1 不透明,0 全透明。
    • alphaBy(float value)
    • rotation(float value) - 2D 旋转
    • rotationBy(float value)
    • rotationX(float value) - 围绕 X 轴 3D 旋转
    • rotationXBy(float value)
    • rotationY(float value) - 围绕 Y 轴 3D 旋转
    • rotationYBy(float value)
    • scaleX(float value) - 大于 1 是放大,小于 1 是缩小
    • scaleXBy(float value)
    • scaleY(float value)
    • scaleYBy(float value)
    • translationX(float value) - 相对于父容器左边 X 轴方向的移动距离
    • translationXBy(float value)
    • translationY(float value)
    • translationYBy(float value)
    • translationZ(float value)
    • translationZBy(float value)
    • x(float value) - 相对于父容器 X 轴方向的绝对位置
    • xBy(float value)
    • y(float value)
    • yBy(float value)
    • z(float value)
    • zBy(float value)
    • setInterpolator(TimeInterpolator interpolator)
    • setListener(Animator.AnimatorListener listener)
    • setStartDelay(long startDelay) - 延时时间
    • setUpdateListener(ValueAnimator.AnimatorUpdateListener listener)
    • start() - 启动动画
    • withLayer() - 设置开启硬件加速
    • withStartAction(Runnable runnable) - 设置用于动画监听开始(Animator.AnimatorListener)时运行的Runnable任务对象
    • withEndAction(Runnable runnable) - 设置用于动画监听结束(Animator.AnimatorListener)时运行的Runnable任务对象

    相关文章

      网友评论

          本文标题:Android 动画总结(5) - 属性动画

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