Android 动画——属性动画Property Animation

  Android在3.0之前只提供了两种动画:View Animation 、Drawable Animation 。也就是我们在《Android 动画——Frame Animation与Tween Animation 》讲解的逐帧动画和补间动画。Android在3.0之后又增加了一种动画类型:Property Animation属性动画 。
  View Animation相当简单,不过只能支持简单的缩放、平移、旋转、透明度基本的动画,且有一定的局限性。比如:你希望View有一个颜色的切换动画;你希望可以使用3D旋转动画;你希望当动画停止时,View的位置就是当前的位置;这些View Animation都无法做到。这就是Property Animation产生的原因,本篇博客详细介绍Property Animation的用法。

相关API

相关属性:

Duration:动画的持续时间,默认300ms。
Interpolation:时间差值,定义动画的变化率。
RepeatCount:重复次数,可以定义重复多少次。
RepeatMode:重复模式,重复播放时,是从头开始播还是反向播。
Animator sets: 动画集合,你可以定义一组动画,一起执行或者顺序执行。
Frame refresh delay:帧刷新延迟,动画多久刷新一次帧;默认为10ms。

相关类:

ValueAnimator 动画的执行类。
ObjectAnimator 动画的执行类,ValueAnimator的子类。
AnimatorSet 用于控制一组动画的执行:线性,一起,每个动画的先后执行等。
AnimatorInflater 用户加载属性动画的xml文件。
TypeEvaluator 类型估值,主要用于设置动画操作属性的值。
TimeInterpolator 时间插值。

Animator

  Animator是动画属性的基类(父类),我们先看一下它的继承结构:
  
这里写图片描述

Animator有两个子类:
ValueAnimator :是属性动画的时间引擎,主要用于为属性动画计算相关属性的值。它也包含两个子类:ObjectAnimator,TimeAnimator
AnimatorSet:用于组合多个Animator。

ValueAnimator的使用

  ValueAnimator使用代码创建和它的子类ObjectAnimator使用代码创建是有区别的。这里先声明一下,在下面讲解到ObjectAnimator我们会具体的说明。ValueAnimator使用代码创建步骤如下:
  
1. 首先调用ValueAnimator如下的静态方法设置相关的属性值:

这里写图片描述

  这里我们调用ofFloat(float… values)属性传入动画在X轴上变化的数值。
  
2. ValueAnimator对象调用setTarget()方法,设置动画实现在哪个对象的身上。
3. ValueAnimator对象调用setDuration()和start()设置动画的显示时间和开始动画。
4. 调用addUpdateListener()方法,在这个监听器中添加相关的操作。
我们来看具体的代码操作:
xml布局文件:(一个按钮开始动画,一个ImageView显示动画)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <Button
            android:id="@+id/button_start"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="开始动画" />

    </LinearLayout>
    <ImageView
        android:id="@+id/imageview_xml"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        android:layout_gravity="center"
        android:onClick="startAnimation"
        android:src="@mipmap/ic_launcher" />

</RelativeLayout>

Activity代码实现:

public class XMLAnimationActivity extends Activity implements View.OnClickListener {

    private Button mButtonStart;
    private ImageView mImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xmlanimation);
        mButtonStart = (Button) findViewById(R.id.button_start);
        mImageView = (ImageView) findViewById(R.id.imageview_xml);
        mButtonStart.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_start:
                //在代码中创建
                ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);//设置属性值
                animator.setTarget(mImageView);//设置操作对象
                animator.setDuration(1000).start();//动画开始
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        mImageView.setScaleY((Float) animation.getAnimatedValue());//设置Y轴上的变化
                        mImageView.setScaleX((Float) animation.getAnimatedValue());//设置X轴上的变化
                    }
                });
                break;
            default:
                break;
        }
    }
}

这里写图片描述

ObjectAnimator的使用

  ObjectAnimator创建有两种方式,一种是在java代码中添加,一种是使用加载xml布局添加。

java代码中创建

在Activity中添加一句话:

ObjectAnimator.ofFloat(mImageView, "ScaleX", 0.0f, 1.0f).setDuration(3000).start();

  ObjectAnimator提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。当对于属性值,只设置一个的时候,会认为当然对象该属性的值为开始(getPropName反射获取),然后设置的值为终点。如果设置两个,则一个为开始、一个为结束。
  动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法。
  
这里写图片描述

xml文件中创建

  为了减轻java代码的负担,我们将对动画的设置定义在xml代码中。
1. 首先在res文件夹下创建一个animator的文件夹。
2. 在animator文件夹下创建一个animator.xml的文件。我们在该xml文件下对动画属性定义。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="scaleX"
        android:valueFrom="0.5f"
        android:valueTo="1.0f">
    </objectAnimator>
</set>

3. 在Activity中:

//使用xml文件加载属性动画方式一
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.animator);//通过该方法,将xml文件导入
anim.setTarget(mImageView);//这是动画的对象
anim.start();//设置动画的开始

这里写图片描述

以下为补充:
  其实在之前还有一种调用方式:在ImageView中添加android:onClick="startAnimation"属性,然后再Activity中定义如下方法:
  注意:该方法已被抛弃,因为他增加了xml布局文件与java文件的耦合性,违背了”高内聚,低耦合“的原则。

    public void startAnimation(View view) {
        //java代码中设置属性操作
        ObjectAnimator.ofFloat(mImageView, "TranslationZ", 0.0f, 1.0f).setDuration(3000).start();    
    }
    public void startAnimation(View view) {
        //xml文件中设置属性操作
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.animator);
        anim.setTarget(mImageView);
        anim.start();      
    }

这里写图片描述

ObjectAnimator与ValueAnimator的不同

我们可以先回顾一下ValueAnimator的使用:

ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);//设置属性值
animator.setTarget(mImageView);//设置操作对象
animator.setDuration(1000).start();//动画开始
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        mImageView.setScaleY((Float) animation.getAnimatedValue());//设置Y轴上的变化
        mImageView.setScaleX((Float) animation.getAnimatedValue());//设置X轴上的变化
    }
});

ObjectAnimator使用:

ObjectAnimator.ofFloat(mImageView, "ScaleX", 0.0f, 1.0f).setDuration(3000).start();

  区别很明显,ValueAnimator调用ofFloat()方法设置了操作的值,而没有设置是何种操作,也就是没有设置操作属性。而ObjectAnimator调用ofFloat()方法设置了操作属性是ScaleX(X轴变化)。
  
  ValueAnimator有没有设置操作的属性,也就是说我们必须在addUpdateListener()方法中定义的监听器中添加相关的属性,否则动画没有任何的操作。那么ValueAnimator这样有什么好处呢?
  
  好处就是,我们不需要操作的对象的属性一定要有getter和setter方法,你可以自己根据当前动画的计算值,来操作任何属性。
  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小_爽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值