Android动画之ObjectAnimator

该文章笔记代码是从慕课网自定义view课程中学习到的,有兴趣的同学可以学习一下

我们在学习动画的时候以前总是用喜欢用Animation的一些子类进行动画的创建或者AnimationSet的集合进行动画的合并,到最后发现,API的耦合性使我并不是特别喜欢用那些对象。

今天看了大神的讲解视频,发现了几个比较好用的动画属性集,下面我将从基础开始逐一介绍。

这是我们学习基础动画时最常用的几个类

常用类.png

我在这里将根据一个小的平移动画(TranslateAnimation)的demo给大家展示我们需要学习的几个类的实现方法。

首先写一个简单的Demo图

xml.jpg

在这里我写了一个imageview和一个button,分别实现了其onClick属性

TranslateAnimation

 public void move(View view) {
        TranslateAnimation ta = new TranslateAnimation(0, 200,0,0);
        ta.setDuration(1000);//持续时间
        ta.setFillAfter(true);//平移完后true代表保存平移后的状态
        imageView.startAnimation(ta);//记得需要findViewById
    }

    public void click(View view) {
        Log.i(TAG, "click: 点击了imageview");
    }

四个构造参数分别为

  • x轴初始坐标
  • x轴的移动坐标
  • y轴初始坐标
  • y轴的移动坐标
    因为我们只是简单的平移,所以只写在x轴上平移即可。
    在click方法中,实现了一个点击安卓机器人图标打印日志的方法,这个需要留意一下,为了铺垫我们为什么要使用后来的ObjectAnimator。

我们来运行一下程序

模拟器.jpg

我们发现,运行出来的结果与我们想的一致,这时候我们点击imageview现在所在的位置,发现出现的问题,Log并没有打印。这是为什么呢

原因是这个方法实现动画的原理在于动画只是在onDraw方法中重新绘制,动画的移动只是视图的单纯移动,所以在平移完后,我们点击图标,相当于点击了个一个空白的布局,如果我们再点击一开始图标初始的位置,我们发现,Log打印了...

你看,这就是个问题,我们该如何解决呢

谷歌官方给我们提供了几个优化好的类

ObjectAnimator

PropertyValuesHolder

AnimatorSet

ObjectAnimator

 public void move(View view) {
        ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f)
        .setDuration(1000).start();//1 操纵的对象 2 所需要操纵的对象属性 3 动画变化的范围
    }

    public void click(View view) {
        Log.i(TAG, "click: 点击了imageview");
    }

创建一个ofFloat的静态方法,三个参数分别为

  1. 绑定好的imageview
  2. 一个平移x轴的字符串(所要操作的对象的属性)
  3. 第三个参数为动画变化的范围,这是一个可变的字符串。
    将这三个参数定义好,再设置一下持续时间以及start()方法,我们就实现了一开始TranslateAnimation类的几行代码了。现在我们运行程序就可以实现同样的效果了。

同时,我们运行项目再次点击平移后机器人图标,发现Log日志可以打印了

那么ObjectAnimator能够实现AnimationSet的动画集合的方法吗,当然可以了

 public void move(View view) {
        ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f).setDuration(1000).start();//1 操纵的对象 2 所需要操纵的对象属性 3 动画变化的范围
        ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f).setDuration(1000).start();//异步过程
        ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f).setDuration(1000).start();
    }

    public void click(View view) {
        Log.i(TAG, "click: 点击了imageview");
    }

我定义了同时从y轴,x轴方向偏移,再加上一个旋转360度的动画,我们来运行一下试一试。


ObjectAnimator.jpg

我们发现,动画在一秒内完成三个动作,同样实现了AnimationSet的效果。而且,我们运行项目再次点击平移后机器人图标,发现Log日志可以打印了。

因为此类需要不停的在onDraw方法进行绘制,特别浪费手机的GPU资源,我们该如何优化了,这时候,另一个类的出现就在某些方面替代了ObjectAnimator

PropertyValuesHolder
PropertyValuesHolder在优化方面优于ObjectAnimator,至于原理,我也不知道,现在我们来讲一下同样的效果,PropertyValuesHolder该如何实现

public void move(View view) {
        //优化
        PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);
        PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationX", 0f, 200f);
        PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("translationY", 0f, 200f);
        ObjectAnimator.ofPropertyValuesHolder(imageView, p1, p2, p3).setDuration(1000).start();
    }

    public void click(View view) {
        Log.i(TAG, "click: 点击了imageview");
    }

通过调用PropertyValuesHolder的静态方法ofFloat,参数与ObjectAnimator.ofFloat参数一致。
最后我们通过ObjectAnimator.ofPropertyValuesHolder方法,将我们绑定好的imageview与定义的三个propertyValuesHolder对象传入。
通过方法链的形式启动动画
最后运行一下项目,发现效果与ObjectAnimator定义时效果一致。

这时候细心的同学应该会发现,AnimationSet是可以定义动画顺序的,那么现在该如何实现呢,别急,还有我们说的最后一个类 AnimatorSet

AnimatorSet

public void move(View view) {
        //更加丰富的控制效果
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
        AnimatorSet set = new AnimatorSet();
        set.playTogether(animator1, animator2, animator3);
        //set.playSequentially(animator1, animator2, animator3);
        //set.play(animator1).with(animator2);
       //set.play(animator2).after(animator3);
        set.setDuration(1000);
        set.start();
    }

    public void click(View view) {
        Log.i(TAG, "click: 点击了imageview");
    }

我们用ObjectAnimator类创建了三个对象
调用Animator的playTogether方法,将三个对象传入最后start,我们发现也实现了上两个类的效果。
我们如何定义顺序呢,我们可以调用set.playSequentially方法,传入,运行项目我们发现顺序就是按照我们传入的三个参数的动画效果执行的。
set.play方法以及with(),after(),before(),又为我们实现了a动画和b动画同时运行完之后接着再运行c动画的需求,我们就可以更加细节化的处理动画了。

在下一节,我们将实现动画的监听事件
源代码
github源代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,896评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,283评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,085评论 0 367
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,010评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,015评论 6 400
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,492评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,858评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,829评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,374评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,409评论 3 346
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,527评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,131评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,858评论 3 339
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,296评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,434评论 1 276
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,087评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,597评论 2 366

推荐阅读更多精彩内容

  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,723评论 0 10
  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 1,926评论 0 10
  • 属性动画和补间动画的不同之处就是它通过动态改变对象的属性从而达到动画效果,它可以对任何对象做动画,并且动画效果也得...
    shenhuniurou阅读 820评论 0 2
  • 转载一篇高质量博文,原地址请戳这里转载下来方便今后查看。1 背景不能只分析源码呀,分析的同时也要整理归纳基础知识,...
    Elder阅读 1,945评论 0 24
  • 叫我12阅读 256评论 0 0