zoukankan      html  css  js  c++  java
  • Android属性动画之ValueAnimator的介绍

    之前两篇博客,介绍的是ObjectAnimator作用与某一个控件的某一个属性。但我们的ValueAnimator它本身并不会作用与任何一个属性,它本身也不会提供任何一种动画。它简单的来说,就是一个数值发生器,它可以产生你想要的各种数值。其实,在Android属性动画中,如何产生每一步具体实现动画效果,都是通过ValueAnimator计算出来的。

    比如我们现在要实现一个从0~100的位移动画,ValueAnimator会根据动画持续的总时间产生一个0~1时间因子,有了这样一个时间因子。通过相应的变幻,就可以根据你的startValue和endValue来生成相应的值。同时,通过插值器的使用,我们还可以进一步控制每一个时间因子它产生值的一个变化速率。如果我们使用线性插值器,那么它生成数值的时候,就会形成一个线性变化,只要时间相同,它的增量也相同。如果我们使用一个加速度的插值器,那么它的增量变化就会呈现一个二次曲线图。增长率会越来越快。由于我们的ValueAnimator并不响应任何一个动画,也不能控制任何一个属性,所以它并没有ObjectAnimator使用的那么广泛。我们还是来看一下如何在程序中使用ValueAnimator吧。

    这里贴一个计时器的动画Demo,activity_main.xml:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent"
     6     tools:context="com.example.administrator.valueanimatordemo.MainActivity">
     7 
     8     <Button
     9         android:id="@+id/btn_click"
    10         android:layout_width="wrap_content"
    11         android:layout_height="wrap_content"
    12         android:layout_centerInParent="true"
    13         android:text="Click Me" />
    14 
    15 </RelativeLayout>

    然后是Java代码的实现,MainActivity.java:

     1 package com.example.administrator.valueanimatordemo;
     2 
     3 import android.animation.TypeEvaluator;
     4 import android.animation.ValueAnimator;
     5 import android.graphics.PointF;
     6 import android.os.Bundle;
     7 import android.support.v7.app.AppCompatActivity;
     8 import android.view.View;
     9 import android.widget.Button;
    10 
    11 public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    12 
    13     private Button btn_click;
    14 
    15     @Override
    16     protected void onCreate(Bundle savedInstanceState) {
    17         super.onCreate(savedInstanceState);
    18         setContentView(R.layout.activity_main);
    19         initView();
    20     }
    21 
    22     private void initView() {
    23         btn_click = (Button) findViewById(R.id.btn_click);
    24         btn_click.setOnClickListener(this);
    25     }
    26 
    27     @Override
    28     public void onClick(View v) {
    29         switch (v.getId()) {
    30             case R.id.btn_click:
    31 //                startAnimator1();//计时器实现
    32 
    33                 //除了startAnimator1()方法中用的ValueAnimator.ofInt(),我们还有
    34                 //ofFloat()、ofObject()这些生成器的方法;
    35                 //我们可以通过ofObject()去实现自定义的数值生成器(请看startAnimator2()方法)
    36                 startAnimator2();
    37                 break;
    38         }
    39     }
    40 
    41     private void startAnimator1() {
    42         final ValueAnimator animator = ValueAnimator.ofInt(0, 100);
    43         animator.setDuration(5000);
    44         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    45             @Override
    46             public void onAnimationUpdate(ValueAnimator animation) {
    47                 /**
    48                  * 通过这样一个监听事件,我们就可以获取
    49                  * 到ValueAnimator每一步所产生的值。
    50                  *
    51                  * 通过调用getAnimatedValue()获取到每个时间因子所产生的Value。
    52                  * */
    53                 Integer value = (Integer) animation.getAnimatedValue();
    54                 btn_click.setText(value + "");
    55             }
    56         });
    57         animator.start();
    58     }
    59 
    60     private void startAnimator2() {
    61         ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
    62             @Override
    63             public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
    64                 return null;
    65             }
    66         });
    67     }
    68 }

    在startAnimator2()方法中,我们既然是生成我们自定义的数值,那就需要new 出TypeEvaluator,并且通过泛型指定我们自定义数值的类型(Demo中暂且为PointF)。通过重写了evaluate这样一个方法,我们可以返回各种各样的值,它的第一个参数fraction就是前面说到的时间因子,它是一个从0~1之间变化的一个数值。还有startValue参数和endValue参数,这些参数结合起来通过各种各样的计算方式,就可以产生所有我们想要产生的值。这里不光能产生普通的数据结构,通过泛型同样可以定义更加复杂的数据结构。

    比如这里用的泛型是PointF,通过重写的evaluate方法,来给我们的Point增加各种各样的计算方式。我们可以修改Point的各种坐标来完成后续的处理。所以,ValueAnimator的功能十分强大,而且很灵活。它可以实现很多意向不到的效果。不仅仅可以使用在动画中,在Android中的很多地方都可以使用。

    总结:

    1、常用属性:

    translationX ranslationY  水平和垂直方向偏移

    rotation、rotationX otationY  rotation指3D翻转,rotationX otationY指水平和竖直方向的一个旋转动画

    scaleXscaleY  X轴方向,和Y轴方向缩放的一个动画

    XY  具体会移动到某一个点

    alpha  透明度动画

    2、常用的方法、类

    ValueAnimator  数值发生器

    ObjectAnimator  是ValueAnimator的一个子类,它封装了ValueAnimator,可以更轻松的使用属性动画

    AnimatorUpdateListener

    AnimatorListenerAdapter  这2个是用来做监听事件的

    PropertyValuesHolder  

    AnimatorSet  这2个用来控制集合动画的一个显示效果、顺序

    TypeEvaluators  值计算器

    Interpolators  插值器,用来控制具体数值的变化规律

  • 相关阅读:
    使用Vue快速开发单页应用
    轻松入门React和Webpack
    使用Redux管理你的React应用
    深入理解 react-router 路由系统
    webpack学习之路
    webpack编译流程漫谈
    HTML5无刷新修改Url,history pushState/replaceState
    gulp的流与执行顺序
    RequireJS对文件合并与压缩实现方法
    RequireJS模块化后JS压缩合并
  • 原文地址:https://www.cnblogs.com/huolongluo/p/6792362.html
Copyright © 2011-2022 走看看