上一篇博客主要介绍了如何使用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动画方面就说到这,写一篇博客还会介绍动画相关的内容的,希望大家多多关注!!
这是我的微信公众号,如果可以的话,希望您可以帮忙关注一下,这将是对我最大的鼓励了,谢谢!!
代码地址:
https://github.com/zhuyuqiang2017/Animation