Android 属性动画 - Keyframe

本文介绍了Android属性动画中的Keyframe,讲解了Keyframe的概念、常用API、使用步骤,并给出了具体的动画实例,展示了如何利用Keyframe实现按钮旋转动画。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android动画系列:

PropertyValuesHolder

PropertyValuesHolder是一个存储器,用来存储动画属性的信息和值,用于使用ValueAnimator或ObjectAnimator创建动画,它们对多个不同的属性并行操作。

valueAnimator

通过PropertyValuesHolder存储“translationX”和“translationY”属性的值。在AnimatorUpdateListener监听的onAnimationUpdate()中,ValueAnimator通过getAnimatedValue(String)方法获取相应动画属性的值,其参数为动画属性的信息,然后在调用相应的setXX(),设置view的属性,其自动调用invalidate()刷新屏幕。

    PropertyValuesHolder holderRight = PropertyValuesHolder.ofFloat(PropertyConstant.PROPERTY_TRANSLATION_X,100f);
    PropertyValuesHolder holderTop = PropertyValuesHolder.ofFloat(PropertyConstant.PROPERTY_TRANSLATION_Y, 300f);

    ValueAnimator valueAnimator = ValueAnimator.ofPropertyValuesHolder(holderRight, holderTop);
    valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
    valueAnimator.setDuration(3000);
    valueAnimator.setTarget(btnProperty);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            float left = (float) valueAnimator.getAnimatedValue(PropertyConstant.PROPERTY_TRANSLATION_X);
            float top = (float) valueAnimator.getAnimatedValue(PropertyConstant.PROPERTY_TRANSLATION_Y);

            btnProperty.setTranslationX(left);
            btnProperty.setTranslationY(top);
        }
    });
    valueAnimator.start();

ObjectAnimator

鉴于ObjectAniator的局限性,PropertyValuesHolder内保存的属性,ObjectAniator

    PropertyValuesHolder holderRight = PropertyValuesHolder.ofFloat(PropertyConstant.PROPERTY_TRANSLATION_X, 100f);
    PropertyValuesHolder holderTop = PropertyValuesHolder.ofFloat(PropertyConstant.PROPERTY_TRANSLATION_Y, 300f);

    ObjectAnimator objectAnimator = ObjectAnimator
            .ofPropertyValuesHolder(btnProperty, holderRight, holderTop)
            .setDuration(3000);
    objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
    objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
    objectAnimator.start();

Keyframe

介绍

KeyFrame成为关键帧,是用来存储时间、值的键值对,实际上存储的是动画的执行进度和动画的属性值,用来定义动画的特定时间的帧。另外,每个关键帧可以拥有自己的插值器,用来控制动画在上一个关键帧和该关键帧的时间之间的间隔中的行为。

KeyFrame本事是一个抽象类。大家都知道的是抽象类本身并不能够实例化,如果想创建KeyFrame的实例,必须使用ofInt(),ofFloat()或ofObject()的工厂方法之一来获得相应类型的关键帧,而在工厂方法中创建的实例实际上是KeyFrame的子类。以ofInt为例:

public abstract class Keyframe implements Cloneable {

    ***

   public static Keyframe ofInt(float fraction, int value) {
        return new IntKeyframe(fraction, value);
    }

    ***

   static class IntKeyframe extends Keyframe {

       ***

        IntKeyframe(float fraction, int value) {
            mFraction = fraction;
            mValue = value;
            mValueType = int.class;
            mHasValue = true;
        }

        IntKeyframe(float fraction) {
            mFraction = fraction;
            mValueType = int.class;
        }

        ***
    }
}

使用Keyframe.ofInt()工厂方法创建KeyFrame实例,实际上是在其方法内创建了IntKeyFrame的实例,而IntKeyFrame是不仅仅是KeyFrame的内部类,同时又是KeyFrame的子类,其内实现了KeyFrame的公共方法,作为工厂模式的产品类。因而调用ofInt()工厂方法可以创建KeyFrame实例。

常用API

  • ofFloat(float fraction):创建KeyFrame实例
  • ofFloat(float fraction, float value):创建KeyFrame实例
  • ofInt(float fraction, int value):创建KeyFrame实例
  • ofInt(float fraction):创建KeyFrame实例
  • ofObject(float fraction, Object value):创建KeyFrame实例
  • ofObject(float fraction):创建KeyFrame实例
  • setInterpolator(TimeInterpolator interpolator):设置KeyFrame的插值器

注:

  1. 参数fraction为动画的执行进度百分比
  2. 参数value为该关键帧的动画属性值

使用步骤

  1. 采用ofInt(),ofFloat()或ofObject()的工厂方法等工厂方法创建KeyFrame实例
  2. 调用ofKeyframe()工厂方法来创建PropertyValuesHolder实例
  3. 通过PropertyValuesHolder实例创建ValueAnimatior实例

动画实例

有这么一个动画效果让Button旋转,在2.5s内从初始位置旋转360度,然后再反向旋转2.5s后回到初始位置。如果用Keyframe该如何处理呢?从动画效果上来看,有3个时间点0s、2.5s、5s,也就是动画应该有三个关键帧,其动画百分比分别说0f、0.5f、1f,动画属性分别说0f、360f、0f。既然分析出了关键帧,这件事事情就好办了。

示例代码及效果图如下:

// 1. 创建Keyframe实例
// 参数1为该关键帧处于动画的执行百分比
// 参数2为该关键字的动画属性值
Keyframe keyframe_0 = Keyframe.ofFloat(0f, 0f);
Keyframe keyframe_1 = Keyframe.ofFloat(0.5f, 360f);
Keyframe keyframe_2 = Keyframe.ofFloat(1f, 0f);

// 设置Keyframe的插值器
keyframe_1.setInterpolator(new LinearInterpolator());
keyframe_2.setInterpolator(new AccelerateDecelerateInterpolator());

//  2. 创建PropertyValuesHolder对象
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe(PropertyConstant.PROPERTY_ROTATION, keyframe_0, keyframe_1, keyframe_2);

// 3. 创建ValueAnimator实例
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(btnProperty, holder);
animator.setDuration(5000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.start();

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值