Android动画之PropertyAnimation;Interpolator;Evaluator与Keyframe

概述

Android中的视图动画和帧动画可以实现大部分的Android中的动画需求,但是有一个缺点,就是其事件响应区域并没有发生变化,这时候出现了属性动画完全弥补了这个缺点

属性动画结构

属性动画

可以看到Animator中主要包括AnimatorSet(动画集合),ValueAnimator,ObjectAnimator,
关于属性动画相关api,可以查看这里android.animation,
属性动画执行时间默认为 300ms.

相关类
  • 监听器类
    Animator.AnimatorListener:动画监听器
    Animator.AnimatorPauseListener:动画暂停监听器
    ValueAnimator.AnimatorUpdateListener:属性更新监听器
    AnimatorListenerAdapter:AnimatorListener空实现类

  • TypeEvaluator 估值类
    IntEvaluator: Int 估值计算
    FloatEvaluator: Float 估值计算
    ArgbEvaluator: 颜色估计算

  • 生成相关类
    AnimatorInflater: 动画生成器,用于从xml生成动画
    AnimatorSet.Builder: 动画构造器,用于设置AnimatorSet
    PropertyValuesHolder: 用于同时设置多个属性动画.

ObjectAnimator

ObjectAnimator 不像ValueAnimator 那样需要用户自己来更新属性,会自动跟新,ObjectAnimator 同样可以在xml和代码中设置.

  • xml 设置,需要放在animator目录下
<!--res/animator/object_animator-->
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="width"
    android:valueFrom="100"
    android:valueTo="20"
    android:valueType="intType" />
ObjectAnimator objectAnimator =
        (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animator);
    objectAnimator.setTarget(wrapper);
    objectAnimator.start();
  • 代码设置
ObjectAnimator animator = ObjectAnimator.ofFloat(_view, "translationX", 300);
    animator.setDuration(1000);
    animator.start();

ObjectAnimator 提供了ofInt、ofFloat、ofObject.其中可以设置的属性必须提供set/get方法,如果没有,可以通过包装类实现,如下实例

public class ViewWrapper {
  private View target; //目标对象
  private int maxWidth; //最长宽度值

  public ViewWrapper(View target, int maxWidth) {
    this.target = target;
    this.maxWidth = maxWidth;
  }

  public int getWidth() {
    return target.getLayoutParams().width;
  }

  public void setWidth(int widthValue) {
    //widthValue的值从100到20变化
    target.getLayoutParams().width = maxWidth * widthValue / 100;
    target.requestLayout();
  }
}

ValueAnimator

ValueAnimator类可以为一些动画指定一系列的int,float,color值。通过调用工厂方法ofInt(),ofFloat(),ofObject()来获取一个ValueAnimator.但是ValueAnimator需要在监听器中获取属性值,更新相关属性

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
         fadeAnim.setDuration(250);
         fadeAnim.addListener(new AnimatorUpdateListener() {
         //...这里也可以用AnimatorListenerAdapter,而不用实现每个回调方法
}

其他常用方法

Object getAnimatedValue();  // 获取当前属性值,可以使int,float,Object
void cancel();//取消动画,动画结束在当前属性值
/** 
 * 移除AnimatorUpdateListener 
 */  
void removeUpdateListener(AnimatorUpdateListener listener);  
void removeAllUpdateListeners();  
 /** 
  * 移除AnimatorListener 
  */  
void removeListener(AnimatorListener listener);  
void removeAllListeners();

AnimatorSet

可以将多个动画按照一定的顺序来一起执行,可以通过代码和xml设置

ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",  
                1.0f, 2f);  
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",  
                1.0f, 2f);  
        AnimatorSet animSet = new AnimatorSet();  
        animSet.setDuration(2000);  
        animSet.setInterpolator(new LinearInterpolator());  
        //两个动画同时执行  
        animSet.playTogether(anim1, anim2);  
        animSet.start(); 
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
  <objectAnimator
     ... />
  <objectAnimator
     .../>
</set>

AnimatorSet支持链式调用,比如 animSet.play().with(); 包含with(),before(),after(),

PropertyValuesHolder

同时在属性动画中提供了一个快捷方式来创建动画,就是PropertyValuesHolder,利用ObjectAnimatorofPropertyValuesHolder方法即可生成其实例.

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,  
                0f, 1f);  
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,  
                0, 1f);  
        PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,  
                0, 1f);  
        ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();  

PropertyValuesHolder方法定义

public static PropertyValuesHolder ofFloat(String propertyName, float... values);
public static PropertyValuesHolder ofInt(String propertyName, int... values);

TimeAnimator

它没有duration、interpolation以及设置值的方法,提供了一个简单的回调机制,通过 TimeAnimator.TimeListener,在动画的每一帧处通知你

//animation:发出通知的动画
//totalTime:动画开始以来的总时间,以毫秒为单位
//deltaTime:从前一帧到现在的运行时间,以毫秒为单位
onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime)

animate

在Android 3.0 之后,还可以使用animate方法来完成属性动画操作,无需调用start()方法,只需要设置相应属性和执行时间即可

mView.animate().x(500).y(500).setDuration(5000); 

Interpolators

Interpolator classResource IDDescription
AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator在动画开始与结束时速率改变比较慢,在中间的时候加速
AccelerateInterpolator@android:anim/accelerate_interpolator在动画开始时速率改变比较慢,然后开始加速
AnticipateInterpolator@android:anim/anticipate_interpolator动画开始的时候向后然后往前抛
AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator动画开始的时候向后然后向前抛,会抛超过目标值后再返回到最后的值
BounceInterpolator@android:anim/bounce_interpolator动画结束的时候会弹跳
CycleInterpolator@android:anim/bounce_interpolator动画循环做周期运动,速率改变沿着正弦曲线
DecelerateInterpolator@android:anim/decelerate_interpolator在动画开始时速率改变比较快,然后开始减速
LinearInterpolator@android:anim/decelerate_interpolator动画匀速播放
OvershootInterpolator@android:anim/overshoot_interpolator动画向前抛,会抛超过最后值,然后再返回

自定义Interpolator

一: 继承Interpolator或其子类

private class DeceAcceInterpolator implements Interpolator{

    @Override public float getInterpolation(float input) {
      return ((4*input-2)*(4*input-2)*(4*input-2))/16f + 0.5f;
    }
  }

二: 自定义xml,更改属性

其中可设置属性包括

Interpolator classAttribute Name
accelerateInterpolatorandroid:factor(浮点值,加速的速率,默认为1)
anticipateInterpolatorandroid:tension(浮点值,向后的拉力,默认为2,当设为0时,则不会有向后的动画了)
anticipateOvershootInterpolatorandroid:tension(同上),android:extraTension(浮点值,拉力的倍数,默认为1.5,当设为0时,则不会有向后的动画了)
cycleInterpolatorandroid:cycles (整数值,循环的次数,默认为1)
decelerateInterpolatorandroid:factor(浮点值,减速的速率,默认为1)
overshootInterpolatorandroid:tension(浮点值,超出终点后的拉力,默认为2)

示例:

<!--res/anim/over_interpolator.xml-->
<?xml version="1.0" encoding="utf-8"?>
<overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:tension="7.0"/>

<!--res/anim/rotate_one_rotate.xml-->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:interpolator="@anim/my_interpolator" 
    android:toDegrees="360"/>

Evaluator

Evaluator其实就是一个转换器,将Interpolator的fraction转变为对应属性的值,如IntEvaluator的定义

public class IntEvaluator implements TypeEvaluator<Integer> {  
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {  
        int startInt = startValue;  
        return (int)(startInt + fraction * (endValue - startInt));  
    }  
}  

系统默认实现有 IntEvaluator,FloatEvaluator,ArgbEvaluator 当没有设置的时候,如果使用的是ofFloat,则默认使用的是FloatEvaluator

具体参考;自定义控件三部曲之动画篇(五)——ValueAnimator高级进阶(一)

Keyframe

Keyframe的意思是关键帧的意思,首先看一下Keyframe的定义

//fraction:表示当前的显示进度.value:表示当前应该在的位置
public static Keyframe ofFloat(float fraction, float value);

同时,可以利用PropertyValuesHolderofKeyframe 方法生成PropertyValuesHolder执行动画 .

public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values);

注意的是至少要有两个帧才行,否则会抛出数组越界异常.

实例

Keyframe frame1 = Keyframe.ofFloat(0.5f, 100f);  
Keyframe frame2 = Keyframe.ofFloat(0.7f,50f);  
PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame1,frame2);  

Animator animator = ObjectAnimator.ofPropertyValuesHolder(mImage, frameHolder);  
animator.setDuration(3000);  
animator.start();

具体参考;自定义控件三部曲之动画篇(八)——PropertyValuesHolder与Keyframe

示例源码地址;AndroidAnimations

参考:Android样式的开发:Property Animation篇
第七章 Android动画机制与使用技巧
自定义控件三部曲之动画篇(八)——PropertyValuesHolder与Keyframe

扩展阅读动画系列 - PropertyAnim 详解
自定义控件三部曲之动画篇(五)——ValueAnimator高级进阶(一)
动画系列 - PropertyAnim 实际应用
浅析Android动画(三),自定义Interpolator与TypeEvaluator
Android中的动画插值器Interpolator:源码及图解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LayoutAnimationController是一个用于对ViewGroup中的子View进行动画控制的类。它主要用于在ViewGroup中添加、删除或重排子View时,对这些子View进行动画控制。 LayoutAnimationController可以通过以下方式创建: ``` LayoutAnimationController lac = new LayoutAnimationController(animation, delay); ``` 其中,animation表示子View的动画效果,delay表示动画延迟时间。 LayoutAnimationController支持以下属性: - order:子View动画的顺序,有三个可选值,分别为normal、reverse和random。 - delay:子View动画的延迟时间,单位为毫秒。 - animation:子View的动画效果。 - interpolator:子View动画的插值器。 以下是一个使用LayoutAnimationController进行子View动画的示例代码: ``` Animation animation = AnimationUtils.loadAnimation(this, R.anim.fade_in); LayoutAnimationController lac = new LayoutAnimationController(animation); lac.setDelay(0.5f); lac.setOrder(LayoutAnimationController.ORDER_NORMAL); LinearLayout container = findViewById(R.id.container); container.setLayoutAnimation(lac); for (int i = 0; i < 10; i++) { TextView textView = new TextView(this); textView.setText("Text " + i); container.addView(textView); } ``` 在上述代码中,我们先通过AnimationUtils加载了一个淡入动画效果,然后创建了一个LayoutAnimationController,并设置了一些属性,最后将LayoutAnimationController应用到LinearLayout容器中。最终,我们在容器中添加了10个TextView,当这些TextView被添加到容器中时,它们会按顺序依次显示,并且每个TextView都会执行一次淡入动画效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值