«

Android之属性动画、值动画

时间:2024-3-2 16:59     作者:韩俊     分类: Android


Android属性动画 什么是Android属性动画 同类技术对比 补间动画Tween Animation 帧动画Frame Animation 属性动画Property Animation 属性动画组成部分相关类介绍 ObjectAnimator对象动画执行类 介绍 示例 ValueAnimator 值动画执行类 介绍 示例 PropertyValuesHolder 属性存储器 介绍 示例 Keyframe 关键帧 介绍 示例 AnimatorSet 执行集合类 介绍 示例 AnimatorUpdateListener动画更新监听 介绍 示例 AnimatorListener 动画执行监听 介绍 示例 AnimatorInflater 动画加载器 介绍 示例 示例 TypeEvaluator 类型估值 介绍 示例 几种常见的插值器 自定义插值器

Android属性动画

什么是Android属性动画

属性动画(Property Animation)系统是一个健壮的动画框架系统,它可以满足你大部分动画需求。不管动画对象是否已经绘制到屏幕上,你都可以在动画执行过程中改变它任意的属性值。一个属性动画会在一段特定长度的时间内改变一个属性(一个对象中的字段)的值。你可以通过以下几步定义一个动画:指定你要执行动画的属性,比如动画对象(View)在屏幕上的位置,指定执行时长,指定你希望的属性的变化值。

同类技术对比:

补间动画(Tween Animation)

渐变动画支持四种类型:平移(Translate)、旋转(Rotate)、缩放(Scale)、不透明度(Alpha)。

只是显示的位置变动,View的实际位置未改变,表现为View移动到其他地方,点击事件仍在原处才能响应。
c. 组合使用步骤较复杂。
d. View Animation 也是指此动画。

帧动画(Frame Animation)

用于生成连续的Gif效果图。
DrawableAnimation也是指此动画。

属性动画(Property Animation)

支持对所有View能更新的属性的动画(需要属性的setXxx()和getXxx())。
更改的是View实际的属性,所以不会影响其在动画执行后所在位置的正常使用。
Android3.0 (API11)及以后出现的功能,3.0之前的版本可使用github第三方开源库nineoldandroids.jar进行支持。

属性动画组成部分、相关类介绍:

ObjectAnimator :对象动画执行类。
ValueAnimator :值动画执行类,常配合AnimatorUpdateListener使用。
PropertyValuesHolder : 属性存储器,为两个执行类提供更新多个属性的功能。
Keyframe :为 PropertyValuesHolder提供多个关键帧的操作值。
AnimatorSet :一组动画的执行集合类:设置执行的先后顺序,时间等。
AnimatorUpdateListener :动画更新监听。
AnimatorListener :动画执行监听,在动画开始、重复、结束、取消时进行回调。
AnimatorInflater :加载属性动画的xml文件。
TypeEvaluator :类型估值,用于设置复杂的动画操作属性的值。
TimeInterpolator :时间插值,用于控制动画执行过程。

ObjectAnimator对象动画执行类

介绍:

通过静态方法ofInt、ofFloat、ofObject、ofPropertyValuesHolder 获取类对象。
根据属性值类型选择静态方法,如view的setLeft(int left) 则选用ofInt方法, setY(float y)则选用ofFloat方法。
同ValueAnimator一样,可以进行串联式使用,示例如下。

示例:

简单示例:View的横向移动

// 通过静态方法构建一个ObjectAnimator对象
// 设置作用对象、属性名称、数值集合
ObjectAnimator.ofFloat(view, "translationX", 0.0F, 200.0F)
// 设置执行时间(1000ms)
.setDuration(1000)
// 开始动画
.start();


2. 复合示例:View弹性落下然后弹起,执行一次。

// 修改view的y属性, 从当前位置移动到300.0f
ObjectAnimator yBouncer = ObjectAnimator.ofFloat(view, "y",
        view.getY(), 300.0f);
yBouncer.setDuration(1500);
// 设置插值器(用于调节动画执行过程的速度)
yBouncer.setInterpolator(new BounceInterpolator());
// 设置重复次数(缺省为0,表示不重复执行)
yBouncer.setRepeatCount(1);
// 设置重复模式(RESTART或REVERSE),重复次数大于0或INFINITE生效
yBouncer.setRepeatMode(ValueAnimator.REVERSE);
// 设置动画开始的延时时间(200ms)
yBouncer.setStartDelay(200);
// 开始动画
yBouncer.start();

ValueAnimator 值动画执行类

介绍:

构造方法与ObjectAnimator类似。
与ObjectAnimator的区别在于ValueAnimator构造函数的参数中不包含动画“属性”信息。
优点:结合动画更新监听onAnimationUpdate使用,可以在回调中不断更新View的多个属性,使用起来更加灵活。

示例:

View向右下角移动:

// 通过静态方法构建一个ValueAnimator对象
// 设置数值集合
ValueAnimator animator = ValueAnimator.ofFloat(0f, 200.0f);
// 设置作用对象
animator.setTarget(view);
// 设置执行时间(1000ms)
animator.setDuration(1000);
// 添加动画更新监听
animator.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        // 获取当前值
        Float mValue = (Float) animation.getAnimatedValue();
        // 设置横向偏移量
        view.setTranslationX(mValue);
        // 设置纵向偏移量
        view.setTranslationY(mValue);
    }
});
// 开始动画
animator.start();

PropertyValuesHolder 属性存储器

介绍:

为ValueAnimator提供多个操作属性及相应的执行参数。

示例:

同时修改View多个属性的动画:

// 获取view左边位置
int left = view.getLeft();
// 获取view右边位置
int right = view.getRight();
// 将view左边增加10像素
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", left,
        left + 10);
// 将view右边减少10像素
PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right",
        right, right - 10);
// 在X轴缩放从原始比例1f,缩小到最小0f,再放大到原始比例1f
PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("scaleX",
        1f, 0f, 1f);
// 在Y轴缩放从原始比例1f,缩小到最小0f,再放大到原始比例1f
PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat("scaleY",
        1f, 0f, 1f);
// 将PropertyValuesHolder交付给ObjectAnimator进行构建
ObjectAnimator customAnim = ObjectAnimator.ofPropertyValuesHolder(view,
        pvhLeft, pvhRight, pvhScaleX, pvhScaleY);
// 设置执行时间(1000ms)
customAnim.setDuration(1000);
// 开始动画
customAnim.start();

Keyframe 关键帧

介绍:

为 PropertyValuesHolder提供关键帧的操作值集合。

示例:

以下示例表示该PropertyValuesHolder进行的旋转(rotation)动画,在执行时间在0%, 50%, 100%时,其旋转角度分别为0°, 360°, 0°。动画执行过程中自动进行补间。表现为自旋360°后再转回来。

// 设置在动画开始时,旋转角度为0度
Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
// 设置在动画执行50%时,旋转角度为360度
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
// 设置在动画结束时,旋转角度为0度
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
// 使用PropertyValuesHolder进行属性名称和值集合的封装
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe(
"rotation", kf0, kf1, kf2);
// 通过ObjectAnimator进行执行
ObjectAnimator.ofPropertyValuesHolder(view, pvhRotation)
// 设置执行时间(1000ms)
.setDuration(1000)
// 开始动画
.start();

AnimatorSet 执行集合类

介绍:

为多个属性动画提供播放顺序控制(注意play,with,after,before的用法)。
AnimatorSet类与AnimationSet类不能搞混,AnimatorSet在3.0及以上版本中才有。3.0之前的版本可使用第三方开源库nineoldandroids.jar进行支持,功能使用完全一致。

示例:

以下示例动画的播放顺序为
1. 播放 bounceAnim;
2. 同时播放 squashAnim1, squashAnim2,stretchAnim1, stretchAnim2;
3. 接着播放 bounceBackAnim;
4. 最后播放 fadeAnim;

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();

AnimatorUpdateListener动画更新监听

介绍:

在动画执行过程中,每次更新都会调用该回调,可以在该回调中手动更新view的属性。
当调用的属性方法中没有进行View的重绘时,需要进行手动触发重绘。设置AnimatorUpdateListener监听,并在onAnimationUpdate回调中执行View的invalidate()方法。

示例:

在回调中手动更新View对应属性:

// 1. 在回调中手动更新View对应属性:
AnimatorUpdateListener l = new AnimatorUpdateListener() {
    public void onAnimationUpdate(ValueAnimator animation) {
        // 当前的分度值范围为0.0f->1.0f
        // 分度值是动画执行的百分比。区别于AnimatedValue。
        float fraction = animation.getAnimatedFraction();
        // 以下的的效果为 View从完全透明到不透明,
        view.setAlpha(fraction);
        // Y方向向下移动300px的距离.
        view.setTranslationY(fraction * 300.0f);
    }
};
ValueAnimator mAnim = ValueAnimator.ofFloat(0f, 1.0f);
mAnim.addUpdateListener(l);
mAnim.setDuration(1000);
mAnim.start();


2. 在自定义View内部用于引发重绘:

// 2. 在自定义View内部用于引发重绘
public class MyAnimationView extends View implements
        ValueAnimator.AnimatorUpdateListener {
    public MyAnimationView(Context context) {
        super(context);
    }
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        // 手动触发界面重绘
        invalidate();
    }
}

AnimatorListener 动画执行监听

介绍:

实现AnimatorListener中的方法可在动画执行全程进行其他任务的回调执行。
也可以添加AnimatorListener的实现类AnimatorListenerAdapter,仅重写需要的监听即可。

示例:

 // 将view透明度从当前的1.0f更新为0.5f,在动画结束时移除该View
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
anim.setDuration(1000);
anim.addListener(new AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        // 动画开始时调用
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
        // 动画重复时调用
    }
    @Override
    public void onAnimationEnd(Animator animation) {
        // 动画结束时调用
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
            parent.removeView(view);
    }
    @Override
    public void onAnimationCancel(Animator animation) {
        // 动画取消时调用
    }
});
anim.start();

AnimatorInflater 动画加载器

介绍:

属性动画可以通过xml文件的形式加载。
set标签内的animator也可单独使用。
XML语法如下:

<setandroid:ordering=["together" ¦ "sequentially"]>
          <objectAnimator
              android:propertyName="string"
              android:duration="int"
              android:valueFrom="float¦ int ¦ color"
              android:valueTo="float¦ int ¦ color"
              android:startOffset="int"
              android:repeatCount="int"
              android:repeatMode=["repeat"¦ "reverse"]
              android:valueType=["intType"¦ "floatType"]/>
          <animator
              android:duration="int"
              android:valueFrom="float¦ int ¦ color"
              android:valueTo="float¦ int ¦ color"
              android:startOffset="int"
              android:repeatCount="int"
              android:repeatMode=["repeat"¦ "reverse"]
              android:valueType=["intType"¦ "floatType"]/>
          <set>
              ...
          </set>
</set>

示例

 // 加载xml属性动画
 Animator anim = AnimatorInflater
         .loadAnimator(this, R.anim.animator_set);
 anim.setTarget(view);
 anim.start();

示例

<?xml version="1.0" encoding="utf-8"?>
<set>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:valueTo="200"
        android:valueType="floatType"
        android:propertyName="x"
        android:repeatCount="1"
        android:repeatMode="reverse"/>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:valueTo="400"
        android:valueType="floatType"
        android:propertyName="y"
        android:repeatCount="1"
        android:repeatMode="reverse"/>
</set>

TypeEvaluator 类型估值

介绍:

TypeEvaluator可传入参数值的类型(本例为PointF)。
重写函数public T evaluate(floatfraction, T startValue, T endValue);实现不同需求值的计算。
注意fraction的使用,fraction是从开始到结束的分度值0.0 -> 1.0。

示例:

// 类型估值 - 抛物线示例
TypeEvaluator<PointF> typeEvaluator = new TypeEvaluator<PointF>() {
    @Override
    public PointF evaluate(float fraction, PointF startValue,
            PointF endValue) {
        float time = fraction * 3;
        Log.e(TAG, time + "");
        // x方向200px/s ,y方向0.5 * 200 * t * t
        PointF point = new PointF();
        point.x = 120 * time;
        point.y = 0.5f * 200 * time * time;
        return point;
    }
};
ValueAnimator valueAnimator = ValueAnimator.ofObject(typeEvaluator,
        new PointF(0, 0));
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setDuration(3000);
valueAnimator.start();

valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        PointF point = (PointF) animation.getAnimatedValue();
        view.setX(point.x);
        view.setY(point.y);
    }
});

几种常见的插值器:

自定义插值器

a.实现Interpolator(TimeInterpolator)接口;
b.重写接口函数float getInterpolation(floatinput)。

标签: android

热门推荐