View layers

  在所有版本的Android中,views都有画到离屏缓冲的能力,这包括使用view的绘制cache,或使用Canvas.saveLayer().离屏缓冲,或者说层,有很多用处.你可以使用它们来为复杂的view动画或使用组合效果时提高性能.例如,你可以使用Canvas.saveLayer()实现淡出效果,这个方法会临时的把一个view画到一个layer中然后使用一个透明系数把它组合回屏幕上.



  从Android3.0 (API level11)开始,你对何时以及如何通过View.setLayerType()方法来使用layer有了更多的控制能力.此方法有两个参数:你想使用的layer的类型和一个可选的Paint对象,这个对象描述了layer应被如何组合.你可以使用Paint参数来应用颜色过滤,或指定混合模式或不透明度到一个layerview可以使用以下三个类型之一:

  • LAYER_TYPE_NONE:view按一般方式绘制,不使用离屏缓冲.这是默认的行为.

  • LAYER_TYPE_HARDWARE:如果应用被硬加速了,view会被绘制到一个硬件纹理中.如果应用没被硬加速,此类型的layer的行为同于LAYER_TYPE_SOFTWARE

  • LAYER_TYPE_SOFTWARE:view被绘制到一个bitmap中.


  要使用哪种layer类型取决于你的目标:

  • 性能:使用一个硬件layer类型把view画到硬件纹理中.当一个view被画到一个layer中,它的绘制代码直到调用invalidate()时才会被执行.一些动画,比如透明变化的动画,可以直接在layer上应用,这对GPU来说轻而易举.

  • 视觉效果:使用硬件或软件layer类型和一个Paint将视觉特效应用到view上.比如,你可以在后台用ColorMatrixColorFilter以黑白色画一个view

  • 兼容性:使用一个软件layer类型来强制view以软件方式绘制.如果一个view是硬加速的(比如,如果你的整个应用是硬加速的),但呈现时出现问题,改用软件方式绘制是一个避开硬件呈现管道限制的最简单的方式.

View layers 和动画

  当你的应用被硬加速时,硬件layer可以提供更快更平滑的动画.当向一个有很多绘制操作的复杂的view应用动画时,要永远保证以60fps的速度运行是不可能的.但这可以通过使用硬件layersview呈现到硬件纹理中来减轻一些负担.硬件纹理之后可以被用来产生动画,避免view为了产生动画而不断的重画自己.view在其属性发生改变而调用invalidate()或你主动调用invalidate()之前不会重画,如果你正在你的应用运行动画但是并不能获得平滑的效果,那么可以考虑在你的动画view上启用硬件layer


  当一个view被硬件layer所支持,它的一些属性的处理就跟layer混合到屏幕上的方式相关了.设置这些属性的操作将变得更高效,因为它们不再导致view变得无效再重绘了.下面列出的就是这些属性,调用这些属性的设置器时会对invalidation操作产生最佳的优化并且不再重画目标view

  • alpha:改变layer的透明度

  • x, y,translationX, translationY:改变layer的位置

  • scaleX,scaleY:改变layer的大小

  • rotation,rotationX, rotationY: 在3D空间中改变layer的方向.

  • pivotX,pivotY: 改变layer的变换原点坐标.

  这些属性是在使用一个ObjectAnimatorview产生动画时使用的.如果你想操作这些属性,调用适当的settergetter即可.例如,要改变透明属性,调用setAlpha().下面的代码片段演示了让一个View绕Y轴进行三维变换的最佳方法:

view.setLayerType(View.LAYER_TYPE_HARDWARE, null);ObjectAnimator.ofFloat(view, "rotationY", 180).start();

  因为硬件 layers使用显卡内存,所以强烈建议你只在动画期间使用它们并在动画结束后禁止它们.你可以使用动画侦听器来做到:

View.setLayerType(View.LAYER_TYPE_HARDWARE, null);ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);animator.addListener(new AnimatorListenerAdapter() {    @Override    public void onAnimationEnd(Animator animation) {        view.setLayerType(View.LAYER_TYPE_NONE, null);    }});animator.start();


提示和技巧

  切换到2D图形硬加速能立即提升性能,但是你仍然需要按照以下建议来有效使用GPU

  • 减少你应用中views的数量

      系统画的views越多,就越慢.这对软件呈现管线来说也是一样.减少views是优化你的UI的最简单的办法.

  • 避免过度绘制

      不要在彼此的上面画太多layers.移除那些完全被别的不透明view遮盖的view们.如果你需要把多个layer混合画到每个view的上面,应考虑把它们合并到一个layer中.对于当前硬件的一个好原则是画的次数不要超过每帧屏幕上像素的2.5倍(透明像素按位图计数)

  • 不要在绘制方法们中创建render对象

      一个常见的错误就是在每次调用绘制方法时都创建新的PaintPath.这强制垃圾收集器运行得更频繁,并且导致高速缓存和硬件管道优化不起作用.

  • 不要太频繁地修改shapes

      比如混合shapes,paths,circles时,是使用纹理遮罩呈现的.每次你创建或修改一个path,硬件管道都创建一个新的遮罩,这个代价是很昂贵的.

  • 不要太频繁地修改bitmap

      你每次改变一个bitmap的内容,你下次去画它时它会作为一个GPU纹理重新上载.

  • 小心使用alpha(透明度)

      当你用setAlpha()AlphaAnimation,或ObjectAnimator把一个view设为透明,它将被呈现到一个离屏缓冲中,此时就需要双倍的填充速率.当在一个very大的view上应用透明度时,应考虑把viewlayer类型设置为LAYER_TYPE_HARDWARE



更多相关文章

  1. Android(安卓)API Guiede---Animation and Graphics
  2. Android中View的绘制
  3. Android(安卓)onDraw触发ImageView的setImageBitmap实现动画,可见
  4. 『Android自定义View实战』自定义带入场动画的弧形百分比进度条
  5. Android(安卓)高仿微信6.0主界面 带你玩转切换图标变色
  6. Android逐条加载ListView,实现动画更新
  7. Android性能优化之工具介绍
  8. Android(安卓)为不同的语言和硬件创建资源
  9. android 字符串绘制示例

随机推荐

  1. sql 修改表的所有者
  2. SQL Server 数据库自动执行管理任务
  3. sql Set IDENTITY_INSERT的用法
  4. 格式导致的Excel导入sql出现异常的解决方
  5. SQL语句 操作全集 学习mssql的朋友一定要
  6. Sql Server datetime问题
  7. 压缩技术给SQL Server备份文件瘦身
  8. SQL Server 2005 还原数据库错误解决方法
  9. SQL Server 存储过程解析
  10. sqlserver 数据类型转换小实验