========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/42531485

——学之开源,用于开源;初学者的心态,与君共勉!
========================================================

用动画用的久了渐渐的喜欢上她了,虽然它或许并不是女的,但我希望是~~

用的久了,我渐渐的思考性能的问题了;在我的一篇([Material Design] MaterialButton 效果进阶 动画自动移动进行对齐效果)介绍按钮点击特效的文章中使用了大量的属性动画,但是在后来我想了很久,其是只需要一个属性动画就能解决所有问题。

下面咱们来说说怎么把多个属性动画合成一个。

开始

一般来说,我们在自定义控件或者控制一些移动操作的时候会使用到这样的属性动画,其是属性动画并不是想象中那么难,只要看看用法举一反三用用就会了~

    private float paintX = 0;private float paintY = 0;private Property<MyView, Float> PaintYProperty = new Property<MyView, Float>(Float.class, "paintY") {@Overridepublic Float get(MyView object) {return object.paintY;}@Overridepublic void set(MyView object, Float value) {object.paintY = value;}};private Property<MyView, Float> PaintXProperty = new Property<MyView, Float>(Float.class, "paintX") {@Overridepublic Float get(MyView object) {return object.paintX;}@Overridepublic void set(MyView object, Float value) {object.paintX = value;}};private void start() {//PaintXObjectAnimator aPaintX = ObjectAnimator.ofFloat(this, PaintXProperty, 0, 100);//PaintYObjectAnimator aPaintY = ObjectAnimator.ofFloat(this, PaintYProperty, 0, 100);//AnimatorSetAnimatorSet set = new AnimatorSet();set.playTogether(aPaintX, aPaintY);set.start();}

在上述的中我们建立了一个关于坐标的属性动画,一般来说坐标含有XY,所以我们定义了两个属性动画;然后打包到一个 AnimatorSet 中管理。至于 AnimatorSet 是什么?你可以理解为这个类是一个属性的管理类,你可以添加 N 多的动画到其中,然后统一调度开启停止;在 AnimatorSet 中维护着一个动画队列。

在上面虽然最后打包到了 AnimatorSet 中进行统一调度,但是你看看 AnimatorSet 中的部分源码你就知道其最后也是启动每一个的属性动画进行启动的。

这也就是我们今天需要想想的地方,你现在完成一个很复杂的操作,其中不但包含一个坐标或者是一堆坐标,也或者包含了很多的颜色变化,此时你使用属性动画就不是一个明智的选择了;为什么呢?你想想你要完成我所说的需要创建多少个属性动画类?很多吧~浪费内存CPU吧?你敢说没有???

既然今天是说优化,那就来优化优化~~

优化

针对上面的情况我们有两种解决方案

第一种

使用一个 Animation ,然后在 protected void applyTransformation(float interpolatedTime, Transformation t)中回调处理具体的情况;具体可以看看我的文章:打造极致Material Design动画风格Button 中有一定的介绍,其效率远远要高于上面的多个属性动画的情况。

第二种

第一种是采用最基本的 Animation 来实现的,这第二种也是使用属性动画。

先看看一部分代码:

   public static class ViewProperty {private float paintX = 0;private float paintY = 0;public ViewProperty() {}public ViewProperty(float paintX, float paintY) {this.paintX = paintX;this.paintY = paintY;}}

是的我们使用一个内部类把所有的属性进行一次封装;然后就可以只使用一个属性动画了;现在看看代码:

   private ViewProperty mProperty = new ViewProperty(0, 0);private Property<MyView, ViewProperty> PaintProperty = new Property<MyView, ViewProperty>(ViewProperty.class, "paintX") {@Overridepublic ViewProperty get(MyView object) {return object.mProperty;}@Overridepublic void set(MyView object, ViewProperty value) {object.mProperty = value;}};private void start() {//PaintObjectAnimator aPaint = ObjectAnimator.ofObject(this, PaintProperty, new ViewProperty(0, 0), new ViewProperty(100, 100));aPaint.start();}

是不是很简单?是不是只有一个属性动画:ObjectAnimator ,是的 ~是的 !

别高兴的太早了~~看看实际情况:

擦~~~这个是怎么了??哪里出错了??

思考

我们应该想想,我们的想法是好的,封装一个属性集合类的实例,然后就可以只使用一个属性动画了;但是问题出在哪里呢?

我们想想,对于Float,Int这些而言,在更改的时候都是采用 C=A+(B-A)*T 这样的情况来的,但是对于Object类型来说呢?这个它怎么减去,怎么运算?

我想这是应该我们去实现的地方,我们需要告诉程序按照什么样的方式去运算: C=A+(B-A)*T 这样的一个公式,告诉它在时间等值情况下进行了10%的时间的时候应该是:new ViewProperty(10, 10),这个值!

TypeEvaluator

public interface TypeEvaluator<T> {/*** This function returns the result of linearly interpolating the start and end values, with* <code>fraction</code> representing the proportion between the start and end values. The* calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,* where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,* and <code>t</code> is <code>fraction</code>.** @param fraction   The fraction from the starting to the ending values* @param startValue The start value.* @param endValue   The end value.* @return A linear interpolation between the start and end values, given the*         <code>fraction</code> parameter.*/public T evaluate(float fraction, T startValue, T endValue);}

在动画类中,有这样的一个接口, 这个接口所完成的工作就是上面的: C=A+(B-A)*T 

其是我们可以看看:

    public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,TypeEvaluator<V> evaluator, V... values) {ObjectAnimator anim = new ObjectAnimator(target, property);anim.setObjectValues(values);anim.setEvaluator(evaluator);return anim;}

在属性动画 ObjectAnimator 类的实例化中有这样的一个构造函数,在该构造函数中就允许用户自己指定自己的运算接口类。

现在我们继承该接口,并实现它:

PaintEvaluator

    public static class PaintEvaluator implements TypeEvaluator {private static final PaintEvaluator sInstance = new PaintEvaluator();public static PaintEvaluator getInstance() {return sInstance;}public Object evaluate(float fraction, Object startValue, Object endValue) {ViewProperty start = (ViewProperty) startValue;ViewProperty end = (ViewProperty) endValue;float x = start.paintX + fraction * (end.paintX - start.paintX);float y = start.paintY + fraction * (end.paintY - start.paintY);return new ViewProperty(x, y);}}

很简单吧。就是分别计算x,y;然后返回一个类的实例就OK了。

结束

然后修改上面的启动代码为:

    private ViewProperty mProperty = new ViewProperty(0, 0);private static PaintEvaluator PAINTEVALUATOR = new PaintEvaluator();private static Property<MyView, ViewProperty> PaintProperty = new Property<MyView, ViewProperty>(ViewProperty.class, "paint") {@Overridepublic ViewProperty get(MyView object) {return object.mProperty;}@Overridepublic void set(MyView object, ViewProperty value) {object.mProperty = value;}};private void start() {//PaintObjectAnimator paint = ObjectAnimator.ofObject(this, PaintProperty, PAINTEVALUATOR, new ViewProperty(0, 0), new ViewProperty(100, 100));paint.start();}

OK,大功告成~~
现在才是够简单,够舒爽~~

祝,大家都能写出称心如意的代码~~

========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/42531485

——学之开源,用于开源;初学者的心态,与君共勉!
========================================================

Android 中关于属性动画的一些思考,或许能为你解决一定的性能问题相关推荐

  1. Android中的属性动画

    1.属性动画简介 接下来我们学习Android动画中的第三种动画--属性动画(Property Animation) Animation一般动画就是我们前面学的帧动画和补间动画!Animator则是本 ...

  2. Android Property Animation属性动画:scale缩放动画(4)

     Android Property Animation属性动画:scale缩放动画(4) 和之前我写的附录文章1,2,3相似,本文将接着使用Android Property Animation属性 ...

  3. android中设置Animation 动画效果

    在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...

  4. android如何播放动画,Android中播放Gif动画取巧的办法

    由于做的项目,要有个动画的等待效果,第一时间想到的就是Gif(懒,省事),但是试了好多据说能播放Gif的控件,也写过,但是放到魅族手机上就是不能播放,所有就想了个招,既然Gif能在浏览器上播放,那an ...

  5. Android开发中遇到的问题(四)——Android中WARNING: Application does not specify an API level requirement!的解决方法

    Android开发中遇到的问题(四)--Android中WARNING: Application does not specify an API level requirement!的解决方法 参考文 ...

  6. 在Android中显示GIF动画

    gif图动画在android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且展示非常好,所以我也想弄一个.经过我多方的搜索资料和整理,终于弄出来了,其实github上有很多开源的gif的展示 ...

  7. android中播放gif动画之一

    在android中默认的控件是不支持gif格式的图片的,只能显示图片的第一帧,这里需要借助于Movie类.将图片进行解析播放.下面使用一种纯代码的自定义控件,这种方式使用方便,但不支持像ImageVi ...

  8. android+属性动画+高度,android 自定义view+属性动画实现充电进度条

    近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和 ...

  9. Android 颜色渐变 属性动画

    最近用到的一个效果,见下图文字颜色渐变 (周围的晃来晃去的框框是轨迹动画,下篇博客说) 1.原理 计算机颜色由红.绿.蓝三色混合组成(值为0-255) 红.绿.蓝之间色值,按照不同大小比例 组成不同颜 ...

  10. Android RatingBar结合属性动画,快速实现 QQ群男女比例分布图效果

    RatingBar介绍 RatingBar作为评分组件,它在实现打分功能的时候确实很方便,并结合了手势触摸事件:RatingBar 的实质是 ProgressBar ,可以看看他的继承关系 java. ...

最新文章

  1. Apache优化配置——工作模式
  2. python给图片添加字符
  3. 根据信号灯状态解决网络故障
  4. 判断页面是否加载完成
  5. BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
  6. Mybatis助手之Mybatis-Plus——开始使用
  7. Bigraph Extension
  8. 在mysql中删除表中字段_MySQL中的表中增加删除字段
  9. java 1.8stream_java jdk1.8 使用stream流进行list 分组归类操作
  10. 贝叶斯数据分析_科研进阶项目 | 剑桥大学 | 心理学、社会学、生物医学:统计数据分析(6.13开课)...
  11. 机器学习及算法-python
  12. 对课程第二次作业的补充与反馈
  13. IDL实现矢量(shp)裁剪栅格TASK(一)
  14. 《符文冲突》unity塔防类游戏试做,经验源码分享-2
  15. 服务器设置来电自动重启,电脑来电自动重启怎么样设置
  16. Codeblock 美化字体和主题
  17. 服务器怎么建立无线局域网,家庭无线局域网的组建教程
  18. 学习笔记-测试利器Mocha
  19. java anon_shiro中的anon,authc啥意思
  20. springboot+Rabit实战一:(Rabbit MQ windows 环境搭建)

热门文章

  1. python docx 表格样式修改 Package not found at ‘*.docx‘; “no style with name ‘Table Grid‘“
  2. LaTeX 修改中文摘要名字
  3. mysql卸载注意问题_mysql卸载注意事项
  4. jsp中使用jsp:include /在切换tomcat版本时遇到的问题
  5. Raki的读paper小记:Sources of Transfer in Multilingual Named Entity Recognition
  6. java read bytes 阻塞_InputStream中read()与read(byte[] b)java InputStream读取数据问题 | 学步园...
  7. Go语言 channel 管道 阻塞 死锁 经典问题
  8. 【字符串】 - 判断是否包含相应的字符 - 截取某一部分字符
  9. 《构建之法》8、9、10
  10. PostgreSQL学习手册(函数和操作符三)