ValueAnimator

ValueAnimator继承自抽象类Animator。要让属性动画渐变式地更改对象中某个属性的值,可分两步操作:第一步,动画需要计算出某一时刻属性值应该是多少;第二步,需要将计算出的属性值赋值给动画的属性。ValueAnimator只实现了第一步,也就是说ValueAnimator只负责以动画的形式不断计算不同时刻的属性值,但需要我们开发者自己写代码将计算出的值通过对象的setXXX等方法更新对象的属性值。

ValueAnimator中有两个比较重要的属性,一个是TimeInterpolator类型的属性,另一个是TypeEvaluator类型的属性。TimeInterpolator指的就是时间插值器,在上面我们已经介绍过,在此不再赘述。TypeEvaluator是什么呢?TypeEvaluator表示的是ValueAnimator对哪种类型的值进行动画处理。ValueAnimator提供了四个静态方法ofFloat()、ofInt()、ofArgb()和ofObject(),通过这四个方法可以对不同种类型的值进行动画处理,这四个方法对应了四种TypeEvaluator,下面会详细说明。

  • public static ValueAnimator ofFloat (float… values) 
    ofFloat方法接收一系列的float类型的值,其内部使用了FloatEvaluator。通过该方法ValueAnimator可以对float值进行动画渐变,其使用方法如下所示:

      ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 500f);
    
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    float deltaY = (float)animation.getAnimatedValue();
    textView.setTranslationY(deltaY);
    }
    }); //默认duration是300毫秒
    valueAnimator.setDuration(3000);
    valueAnimator.start();

    其效果如下所示: 

    我们通过构造函数指定了动画的起始值为0,终止值为500,动画的默认持续时间是300毫秒,我们通过setDuration()方法设置为3000毫秒。该动画会在3秒内,将值从0到500动画渐变。ValueAnimator提供了一个addUpdateListener方法,可以通过该方法向其添加AnimatorUpdateListener类型的监听器。AnimatorUpdateListener有一个onAnimationUpdate方法,ValueAnimator会每隔一定时间(默认间隔10ms)计算属性的值,每当计算的时候就会回调onAnimationUpdate方法。在该方法中,我们通过调用ValueAnimator的getAnimatedValue()方法获取到当前动画计算出的属性值,然后我们将该值传入textView的setTranslationY()方法中,从而更新了textView的位置,这样就通过ValueAnimator以动画的形式移动textView。

  • public static ValueAnimator ofInt (int… values) 

    ofInt方法与ofFloat方法很类似,只不过ofInt方法接收int类型的值,ofInt方法内部使用了IntEvaluator,其具体使用可参考上面ofFloat的使用代码,在此不再赘述。

  • public static ValueAnimator ofArgb (int… values) 

    从API Level 21开始,ValueAnimator中加入了ofArgb方法,该方法接收一些列代表了颜色的int值,其内部使用了ArgbEvaluator,可以用该方法实现将一个颜色动画渐变到另一个颜色,我们从中可以不断获取中间动画产生的颜色值。你可能纳闷,既然传入的还是int值,那直接用ofInt方法不就行了吗,干嘛还要新增一个ofArgb方法呢?实际上用ofInt方法是不能完成颜色动画渐变的。我们知道一个int值包含四个字节,在Android中第一个字节代表Alpha分量,第二个字节代表Red分量,第三个字节代表Green分量,第四个字节代表Blue分量,且我们常用16进制表示颜色,这样看起来更明显易懂一些,比如int值0xffff0000表示的红色,0xff00ff00表示的是绿色,最前面的ff表示的是Alpha。ofArgb方法会通过ArgbEvaluator将颜色拆分成四个分量,然后分别对各个分量进行动画计算,然后将四个计算完的分量再重新组合成一个表示颜色的int值,这就是ofArgb方法的工作原理。使用方法如下所示:

    //ValueAnimator.ofArgb()方法是在API Level 21中才加入的
    if(Build.VERSION.SDK_INT >= 21){
    //起始颜色为红色
    int startColor = 0xffff0000;
    //终止颜色为绿色
    int endColor = 0xff00ff00;
    ValueAnimator valueAnimator = ValueAnimator.ofArgb(startColor, endColor);
    valueAnimator.setDuration(3000);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    int color = (int)animation.getAnimatedValue();
    textView.setBackgroundColor(color);
    }
    });
    valueAnimator.start();
    }

    效果如下所示: 

    我们将TextView的颜色通过动画从红色渐变到绿色。

  • public static ValueAnimator ofObject (TypeEvaluator evaluator, Object… values) 
    由于我们要进行动画处理的值是各种各样的,可能不是float、int或颜色值,那我们怎么使用属性动画呢?为此,ValueAnimator提供了一个ofObject方法,该方法接收一个TypeEvaluator类型的参数,我们需要实现该接口TypeEvaluator的evaluate方法,只要我们实现了TypeEvaluator接口,我们就能通过ofObject方法处理任意类型的数据。我们之前提到ofArgb方法是从API Level 21才引入的,如果我们想在之前的这之前的版本中使用ofArgb的功能,怎么办呢?我们可以扩展TypeEvaluator,从而通过ofObject方法实现ofArgb方法的逻辑,如下所示:

     //起始颜色为红色
    int startColor = 0xffff0000;
    //终止颜色为绿色
    int endColor = 0xff00ff00;
    ValueAnimator valueAnimator = ValueAnimator.ofObject(new TypeEvaluator() {
    @Override
    public Object evaluate(float fraction, Object startValue, Object endValue) {
    //从初始的int类型的颜色值中解析出Alpha、Red、Green、Blue四个分量
    int startInt = (Integer) startValue;
    int startA = (startInt >> 24) & 0xff;
    int startR = (startInt >> 16) & 0xff;
    int startG = (startInt >> 8) & 0xff;
    int startB = startInt & 0xff; //从终止的int类型的颜色值中解析出Alpha、Red、Green、Blue四个分量
    int endInt = (Integer) endValue;
    int endA = (endInt >> 24) & 0xff;
    int endR = (endInt >> 16) & 0xff;
    int endG = (endInt >> 8) & 0xff;
    int endB = endInt & 0xff; //分别对Alpha、Red、Green、Blue四个分量进行计算,
    //最终合成一个完整的int型的颜色值
    return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
    (int)((startR + (int)(fraction * (endR - startR))) << 16) |
    (int)((startG + (int)(fraction * (endG - startG))) << 8) |
    (int)((startB + (int)(fraction * (endB - startB))));
    }
    }, startColor, endColor);
    valueAnimator.setDuration(3000);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    int color = (int)animation.getAnimatedValue();
    textView.setBackgroundColor(color);
    }
    });
    valueAnimator.start();

    以上代码实现的效果与ofArgb实现的效果是一样的,都是将TextView从红色渐变到绿色,但是我们可以在API Level 11及以后的版本中都可以使用以上ofObject的代码,通用性更强。

  • 效果图:

android 开发 View _3_ View的属性动画ValueAnimator的更多相关文章

  1. Android开发教程AnimationDrawable逐帧播放动画

    下面我们一起来看篇Android开发AnimationDrawable控制逐帧播放动画实现过程,希望文章对各位朋友带不一些帮助. 当我们点击按钮时,该图片会不停的旋转,当再次点击按钮时,会停止在当前的 ...

  2. android开发_view和view属性

    一.view视图的宽度和高度属性,属性值:固定和浮动两种状态 1属性为固定值 <View android:layout_width="30dp" android:layout ...

  3. android开发之自定义View 详解 资料整理 小冰原创整理,原创作品。

    2019独角兽企业重金招聘Python工程师标准>>> /** * 作者:David Zheng on 2015/11/7 15:38 * * 网站:http://www.93sec ...

  4. Android开发进阶——自定义View的使用及其原理探索

    在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...

  5. Android基础夯实--重温动画(四)之属性动画 ValueAnimator详解

    宝剑锋从磨砺出,梅花香自苦寒来:千淘万漉虽辛苦,吹尽狂沙始到金: 长风破浪会有时,直挂云帆济沧海 一.摘要 Animator类作为属性动画的基类,它是一个抽象类,它提供了实现动画的基本架构,但是我们不 ...

  6. Android属性动画-ValueAnimator和ObjectAnimator的高级用法

    ValueAnimator的高级用法 在上篇文章中介绍补间动画缺点的时候有提到过,补间动画是只能对View对象进行动画操作的.而属性动画就不再受这个限制,它可以对任意对象进行动画操作.那么大家应该还记 ...

  7. Android使用属性动画ValueAnimator动态改变SurfaceView的背景颜色

    以下是主要代码,难点和疑问点都写在注释中: /** * 开始背景动画(此处为属性动画) */ private void startBackgroundAnimator(){ /* *参数解释: *ta ...

  8. 属性动画 ValueAnimator 运行原理全解析

    最近下班时间都用来健身还有看书了,博客被晾了一段时间了,原谅我~~~~ 提问环节 好,废话不多说,之前我们已经分析过 View 动画 Animation 运行原理解析,那么这次就来学习下属性动画的运行 ...

  9. 属性动画ValueAnimator用法

    用法举例: 1. ValueAnimator animator = ValueAnimator.ofInt(0,100);//定义animator 2. animator.addUpdateListe ...

随机推荐

  1. Android : 跟我学Binder --- (2) AIDL分析及手动实现

    目录: Android : 跟我学Binder --- (1) 什么是Binder IPC?为何要使用Binder机制? Android : 跟我学Binder --- (2) AIDL分析及手动实现 ...

  2. 容器的注入和container设计的思想——Injection Container 理解

    为什么会出现容器的注入? 容器:顾名思义,装东西的器物. 至于spring中bean,aop,ioc等一些都只是实现的方式:具体容器哪些值得我们借鉴,我个人觉得是封装的思想.将你一个独立的系统功能放到 ...

  3. browser-sync第一次打开提示路径错误,path.js应该输出字符串;之后重启一直提示插入代码片段,插入后无效依然提示

    网上找到gulp类似提示,是node版本问题. nvm派上用场, browser-sync@2.23.6,node用的8.3.0 解决办法: nvm install 7.8.0 nvm use 7.8 ...

  4. Mysql5.7实现主从复制、基于GTID的主从复制、并行复制

    (一.主从复制) 一.mysql主从复制原理    mysql的默认复制方式是主从复制.Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制, ...

  5. 群等变网络的pytorch实现

    CNN对于旋转不具有等变性,对于平移有等变性,data augmentation的提出就是为了解决这个问题,但是data augmentation需要很大的模型容量,更多的迭代次数才能够在训练数据集合 ...

  6. Vagrant 命令详解

    1.查看当前登录的用户系统上所有活动的Vagrant环境的状态. vagrant global-status参数:--prune 清除列表中的无效条目   ... ...    

  7. mysql in 查询参数化

    mysql查询语句where条件in mysql查询语句where条件in 正常情况需要查询的语句:select *from temp where id in ('1','2','3','4','5' ...

  8. POJ1821 Fence

    题意 Language:Default Fence Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6478 Accepted: ...

  9. 【转载】Win10系统桌面右键新建没有Word、Excel、PPT怎么恢复?

    Win10系统桌面右键新建没有Word.Excel.PPT怎么恢复? 以下正文转载至: 网址:http://www.xitongzhijia.net/xtjc/20170307/93471.html ...

  10. 在Cygwin中出现JAVA_HOME出现故障找不到出现故障

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012516914/article/details/37689937 JAVA_HOME出现故障后查 ...