ValueAnimator的简单介绍和使用

上一篇博客主要介绍了如何使用ObjectAnimator来实现我们想要的动画效果。ObjectAnimator是ValueAnimator的子类。上一篇博客中的动画也可以通过使用ValueAnimator动画来实现,在这一篇博客中,我就来介绍如何使用ValueAnimator来实现这些动画!!!ValueAnimator和ObjectAnimator一样,既可以通过在xml中声明也可以在java代码中声明,长久以来我都不用java代码中声明animator,这次我就使用java代码来生成animator实例(其实是因为使用xml声明过valueAnimator动画之后,还是需要通过代码来设置动画更新的监听事件,不如都是用java代码来设置来的痛快)。好了废话不多说,先看一下效果图,由于所有的动画动一样,为了与上一篇ObjectAnimator动画区别,我使用了弹性插值器,具体的在讲述到代码的时候在详说!!!
效果图:

主布局文件:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="2">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:src="@mipmap/ic_launcher" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <GridLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:columnCount="2">

            <Button
                style="@style/custom_button"
                android:onClick="startScaleXAnimator"
                android:text="@string/start_scale_x" />

            <Button
                style="@style/custom_button"
                android:onClick="startScaleYAnimator"
                android:text="@string/start_scale_y" />

            <Button
                style="@style/custom_button"
                android:onClick="startAlphaAnimator"
                android:text="@string/start_alpha" />

            <Button
                style="@style/custom_button"
                android:onClick="startRotateAnimator"
                android:text="@string/start_rotate" />

            <Button
                style="@style/custom_button"
                android:onClick="startRotateXAnimator"
                android:text="@string/start_rotate_x" />

            <Button
                style="@style/custom_button"
                android:onClick="startRotateYAnimator"
                android:text="@string/start_rotate_y" />

            <Button
                style="@style/custom_button"
                android:onClick="startTranslationXAnimator"
                android:text="@string/start_translation_x" />

            <Button
                style="@style/custom_button"
                android:onClick="startTranslationYAnimator"
                android:text="@string/start_translation_y" />
        GridLayout>
        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            style="@style/custom_button"
            android:text="@string/app_name"
            android:onClick="startSetAnimator"/>
    LinearLayout>

LinearLayout>

java文件:

package com.example.valueanimatordemo;

import android.animation.ValueAnimator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private ValueAnimator mValueAnimator;
    private ImageView iv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mValueAnimator = new ValueAnimator();
        mValueAnimator.setFloatValues(0.0f,1.0f,2.0f,3.0f);
        mValueAnimator.setDuration(5000);
        mValueAnimator.setInterpolator(new BounceInterpolator());
        iv = (ImageView) findViewById(R.id.iv);
        mValueAnimator.setEvaluator(null);
    }
    public void startScaleXAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        final float ivScaleX = iv.getScaleX();
        AnimatorUpdateListener scaleX = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float rate = (float) animation.getAnimatedValue();
                iv.setScaleX(ivScaleX*(1+rate));
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(scaleX);
        mValueAnimator.start();
    }

    public void startScaleYAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        final float ivScaleY = iv.getScaleY();
        AnimatorUpdateListener scaleY = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float rate = (float) animation.getAnimatedValue();
                iv.setScaleY(ivScaleY*(1+rate));
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(scaleY);
        mValueAnimator.start();
    }

    public void startAlphaAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        mValueAnimator.setFloatValues(1.0f,0.3f);
        final float alpha = iv.getAlpha();
        AnimatorUpdateListener mAlpha = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float rate = (float) animation.getAnimatedValue();
                iv.setAlpha(rate*alpha);
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(mAlpha);
        mValueAnimator.start();
    }

    public void startRotateAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        mValueAnimator.setFloatValues(0.0f,360f);
        AnimatorUpdateListener mRotate = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                iv.setRotation(value);
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(mRotate);
        mValueAnimator.start();
    }

    public void startRotateXAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        mValueAnimator.setFloatValues(0.0f,360f);
        AnimatorUpdateListener mRotateX = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                iv.setRotationX(value);
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(mRotateX);
        mValueAnimator.start();
    }

    public void startRotateYAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        mValueAnimator.setFloatValues(0.0f,360f);
        AnimatorUpdateListener mRotateY = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                iv.setRotationY(value);
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(mRotateY);
        mValueAnimator.start();
    }

    public void startTranslationXAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        mValueAnimator.setFloatValues(0,0f,400f);
        AnimatorUpdateListener mLocationX = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
//                iv.setX(value);//滑动的起始点为原点
                iv.setTranslationX(value);//滑动的起始点为view所在的X点
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(mLocationX);
        mValueAnimator.start();
    }

    public void startTranslationYAnimator(View view) {
        mValueAnimator.removeAllUpdateListeners();
        mValueAnimator.setFloatValues(0,0f,400f);
        AnimatorUpdateListener mLocationY = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                float rate = animation.getAnimatedFraction();
//                iv.setY(value);//滑动的起始点为原点
                iv.setTranslationY(value);//滑动的起始点为view所在的X点
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(mLocationY);
        mValueAnimator.start();
    }

    public void startSetAnimator(View view){
        mValueAnimator.removeAllUpdateListeners();
        mValueAnimator.setFloatValues(1.0f,0.3f);
        final float alpha = iv.getAlpha();
        final float scaleX = iv.getScaleX();
        final float scaleY = iv.getScaleY();
        AnimatorUpdateListener set = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float rate = (float) animation.getAnimatedFraction();
                iv.setScaleX(scaleX+(rate*scaleX)*3);
                iv.setScaleY(scaleY+(rate*scaleY)*3);
                iv.setRotation(rate*360f);
//                iv.setRotationX(rate*360f);
//                iv.setRotationY(rate*360f);
                iv.setAlpha(rate*alpha);
                if(iv.getAlpha()<0.3){
                    iv.setAlpha(0.3f);
                }
            }
        };
        mValueAnimator.setTarget(null);
        mValueAnimator.addUpdateListener(set);
        mValueAnimator.start();
    }
}

在使用ValueAnimator的时候,除了一个插值器之外,还多了一个差值器!在这里我们简单说一下,在下一篇博客中,我们在详细说一下估值器的作用。
估值器就是动画状态更新的一个回调,方法传入的一个ValueAnimator实例,我们可以通过这个实例获取动画的值,如果是控制ScaleX,那么我们获取的值就是一个float值,根据这个值来重新更新View的ScaleX。不过ValueAnimator的动画值也是计算出来的,那么计算的依据是什么呢,相信你已经猜到了吧!!没错就是插值器传出的值,要知道插值器传出的值范围在0~1之间,这代表的是动画的进度,而估值器就是根据插值器返回的值计算当前时刻动画的值。而且无论是插值器还是估值器我们都可以自定义的,好了,不说了,下一篇博客在详说吧!!!

其实单一控制一个属性的动画很容易实现的,但是每次看到其他优秀APP上的动画就感觉没头绪有没有,这其实是因为我们接触的还不够多,相信在不断的学习的情况,在不远的将来,那些我们现在看起来很复杂的动画,都可以轻易实现的!!

好了,关于valueAnimator动画方面就说到这,写一篇博客还会介绍动画相关的内容的,希望大家多多关注!!

这是我的微信公众号,如果可以的话,希望您可以帮忙关注一下,这将是对我最大的鼓励了,谢谢!!
ValueAnimator的简单介绍和使用_第1张图片

代码地址:
https://github.com/zhuyuqiang2017/Animation

你可能感兴趣的:(Android)