本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning

译三:

优化视图

关于如何设计自定义View以及响应触摸时间等,请看Android developer :

地址:http://developer.android.com/training/custom-views/index.html

本文翻译地址:Optimizing the View

通过前面的学习,现在该设计良好的View能够响应手势以及状态之间进行转换,除此之外你必须确保View

运行的流畅快速。为了避免迟缓的UI效果或者运行的停顿,必须确保你的动画一直运行在每秒60帧。

越少越好

为了加速视图,从那些调用频繁的活动中减少不必要的代码。在OnDraw()方法中开始绘制,它会给你最大的

效益。特别低,你也应该减少在onDraw()方法中的内存分配,因为任何内存分配都可能导致内存回收,这将会

引起不连贯。 在初始化或者动画之间分配对象。绝不要在动画运行时分配内存。

另一方面需要减少onDraw()方法中的开销,只在需要时才调用onDraw()方法。通常invalidate()方法会调用

onDraw()方法,因此减少对invalidate()的不必要调用。如果可能,调用它的重载版本即带有参数的invalidate()

方法而不是无参的invalidate()方法。该带参数的方法invalidate()能使draw过程更有效,以及减少对落在该矩形

区域(参数指定的区域)外视图的不必要重绘 。

注,invalidate()的三个重载版本为:

1 、public void invalidate (Rect dirty)
            2、public void invalidate (int l, int t, int r, int b)

3、public void invalidate ()

另外的一个高代价的操作是布局过程(layout)。 任何时刻对View调用requestLayout()方法,Android UI 框架

都需要遍历整个View树,确定每个视图它们所占用的大小。如果在measure过程中有任何冲突,可能会多次遍历

View树。UI设计人员有时为了实现某些效果,创建了较深层次的ViewGroup。但这些深层次View树会引发效率

问题。确保你的View树层次尽可能浅。

如果你有的UI设计是复杂地,你应该考虑设计一个自定义ViewGroup来实现layout过程。不同于内置View控件,

自定义View能够假定它的每个子View的大小以及形状,同时能够避免为每个子View进行measure过程。 PieChart

展示了如何继承ViewGroup类。 PieChart带有子View,但它从来没有measure它们。相反,它根据自己的布局算法

去直接设置每个子View的大小。

如下代码所示:

  1. /**
  2. * Custom view that shows a pie chart and, optionally, a label.
  3. */
  4. public class PieChart extends ViewGroup {
  5. ...
  6. //
  7. // Measurement functions. This example uses a simple heuristic: it assumes that
  8. // the pie chart should be at least as wide as its label.
  9. //
  10. @Override
  11. protected int getSuggestedMinimumWidth() {
  12. return (int) mTextWidth * 2;
  13. }
  14. @Override
  15. protected int getSuggestedMinimumHeight() {
  16. return (int) mTextWidth;
  17. }
  18. @Override
  19. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  20. // Try for a width based on our minimum
  21. int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
  22. int w = Math.max(minw, MeasureSpec.getSize(widthMeasureSpec));
  23. // Whatever the width ends up being, ask for a height that would let the pie
  24. // get as big as it can
  25. int minh = (w - (int) mTextWidth) + getPaddingBottom() + getPaddingTop();
  26. int h = Math.min(MeasureSpec.getSize(heightMeasureSpec), minh);
  27. setMeasuredDimension(w, h);
  28. }
  29. @Override
  30. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  31. // Do nothing. Do not call the superclass method--that would start a layout pass
  32. // on this view's children. PieChart lays out its children in onSizeChanged().
  33. }
  34. @Override
  35. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  36. super.onSizeChanged(w, h, oldw, oldh);
  37. //
  38. // Set dimensions for text, pie chart, etc
  39. //
  40. // Account for padding
  41. ...
  42. // Lay out the child view that actually draws the pie.
  43. mPieView.layout((int) mPieBounds.left,
  44. (int) mPieBounds.top,
  45. (int) mPieBounds.right,
  46. (int) mPieBounds.bottom);
  47. mPieView.setPivot(mPieBounds.width() / 2, mPieBounds.height() / 2);
  48. mPointerView.layout(0, 0, w, h);
  49. onDataChanged();
  50. }
  51. }

使用硬件加速

Android 3.0版本后,Android 2D图形库能在大多数Android设备上使用GPU(图形处理单元)加速。GPU硬件

加速可以极大的优化多数应用程序,但它并不是每个应用程序的最优选择。Android框架给予你是否在应用程序中

使用硬件加速的控制力。

<<如何运用硬件加速>>篇展示了如何在Application、Activity、Window级别中使用硬件加速。值得注意的是

我们必须手动在配置文件中设置应用程序API级别为11或者更高级别,即在 AndroidManifest.xml进行如下配置:
  <uses-sdk android:targetSdkVersion="11"/>

一旦你开启了硬件加速,你可能看不到效率的提升。Mobile GPUs 善于处理特定的任务,例如:伸缩、旋转、

平移图片。它也有一些不擅长处理的任务,例如:绘制直线或曲线。常言道物尽其用,扬长避短,尽可能让GPU

处理它擅长的任务,减少让其处理弱势任务的。

在PieChart 示例中,例如,相对来说绘制一个圆形是比较耗费资源的。每次旋转引起的重绘导致UI的迟缓。

解决办法就是让View来呈现该圆形,并且设置该View的layer type属性为 LAYER_TYPE_HARDWARE,因此GPU

能够缓存静态图片。示例中该View作为 PieChart类的内部类存在,减少了为了实现这个方法的代码开销。

  1. private class PieView extends View {
  2. public PieView(Context context) {
  3. super(context);
  4. if (!isInEditMode()) {
  5. setLayerType(View.LAYER_TYPE_HARDWARE, null);
  6. }
  7. }
  8. @Override
  9. protected void onDraw(Canvas canvas) {
  10. super.onDraw(canvas);
  11. for (Item it : mData) {
  12. mPiePaint.setShader(it.mShader);
  13. canvas.drawArc(mBounds,
  14. 360 - it.mEndAngle,
  15. it.mEndAngle - it.mStartAngle,
  16. true, mPiePaint);
  17. }
  18. }
  19. @Override
  20. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  21. mBounds = new RectF(0, 0, w, h);
  22. }
  23. RectF mBounds;
  24. }

改变之后,只有View第一次显示的时候才会调用PieChart.PieView.onDraw()方法。在应用程序的其他

时间,绘制的图像将会作为图片缓存,重绘时GPU将任意旋转图像。

然而这只是一个折中手段。缓存图片作为硬件层导致 video memory开销,video memory却是一种受限制的

资源。 出于这个原因,在PieChart.PieView的最终版本上,只有在用户滑动时才设置它的layer type属性为

LAYER_TYPE_HARDWARE。在其他时间,仅仅设置它的layer type属性为 LAYER_TYPE_HARDWARE,这

允许GPU停止缓存图片。

最后,不要忘记分析你的代码。在一个View上做的优化技术可能会在其他View上产生不好的影响。

Android中View绘制优化之三---- 优化View的更多相关文章

  1. Android 中对于图片的内存优化方法

    Android 中对于图片的内存优化方法,需要的朋友可以参考一下     1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFact ...

  2. Android中数据库Sqlite的性能优化

    1.索引简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率.(1). 优点大大加快了数据库检索的速度,包括 ...

  3. Android 中的Activity、Window、View之间的关系

    一.概述   Activity 可以说是应用程序的载体(也可以理解为界面的载体,但是不界面),用户能够在上面绘制界面(Activity本身不绘制界面),并提供用户处理事件的API,维护应用程序的生命周 ...

  4. 【腾讯bugly干货分享】Android自绘动画实现与优化实战——以Tencent OS录音机波形动

    前言 本文为腾讯bugly的原创内容,非经过本文作者同意禁止转载,原文地址为:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1180 ...

  5. 4.View绘制分析笔记之onDraw

    上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...

  6. Android中使用ViewPager实现广告条

    我们在使用电商或视频的手机客户端时,通常会看到广告条的效果.在网上搜索时才知道使用的是ViewPager,于是自己也做了一个Demo. 以下是效果图: 图中包括背景图片.文字描述以及白点. 其中Vie ...

  7. Android中View绘制优化之一---- 优化布局层次

    本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning 前言,竟然是翻译,当然得弄的有板有眼. 照着大作家格式来咯 , - - . 译序 最近一直在做锁屏界面,之前也 ...

  8. Android中View绘制优化

    1.优化布局层次 http://www.2cto.com/kf/201209/154108.html 2.使用<include />标签复用布局文件 http://www.2cto.com ...

  9. Android中View绘制优化二一---- 使用<include />标签复用布局文件

    本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning   译二:   使用<include />标签复用布局文件      翻译地址:http://de ...

随机推荐

  1. CSS 规避脱标之两种用法

    大家好,我是小强老师,今天讲解一小点知识哈 对比了才知道什么好 看不出,很漂亮吧! 有木有倾国倾城的美色. 呵呵,好多东西也是这样的,好的东西只有对比了才觉得好. 我们知道我们网页布局 有三模式.   ...

  2. 转:CSS选择器笔记

    作者: 阮一峰 日期: 2009年3月12日 去年我学jQuery的时候,曾经做过一点选择器(selector)的笔记. 这几天拿出来看了一下,发现很多都忘记了.所以,我决定把它们贴在这里,方便以后查 ...

  3. JavaScript自调用匿名函数

    Self-Invoking Anonymous Function,即自调用匿名函数.顾名思义,该函数没有名称,不同的是,该函数定义后立即被调用.该函数的作用是在应用中初始化或做一次性工作. 普通匿名函 ...

  4. [置顶] 浏览器模式和标准对于javascript的影响

    今天在编写代码的时候遇到了一个莫名其妙的问题,请看下面 <html> <head> <title> Test </title> <!--<m ...

  5. CF(437C)The Child and Toy(馋)

    意甲冠军:给定一个无向图,每个小点右键.操作被拉动所有点逐一将去,直到一个点的其余部分,在连边和点拉远了点,在该点右点的其余的费用.寻找所需要的最低成本的运营完全成本. 解法:贪心的思想,每次将剩余点 ...

  6. Android跟蓝牙耳机建立连接有两种方式

    Android 跟蓝牙耳机建立连接有两种方式. 1. Android 主动跟蓝牙耳机连BluetoothSettings 中和蓝牙耳机配对上之后, BluetoothHeadsetService 会收 ...

  7. SQL 局域网远程备份

     局域网远程备份,还真有点问题 我用的是2003,发现sql和windows兼容不太好 . 如果我在windows下面映射远程目录,sql发现不了,找不到路径,备份不了,在sql下映射远程目录,win ...

  8. BZOJ 3211: 花神游历各国( 线段树 )

    线段树...区间开方...明显是要处理到叶节点的 之前在CF做过道区间取模...差不多, 只有开方, 那么每个数开方次数也是有限的(0,1时就会停止), 最大的数10^9开方10+次也就不会动了.那么 ...

  9. java--异常处理总结

    [在程序中抛出异常] 在程序中抛出异常,一定要使用关键字throw. throw+异常实例对象. public class Demo2 { public static void main(String ...

  10. ZYSocket 4.3.5 SOCKET框架组 发布[NEW]

    最新代码请到 github: https://github.com/luyikk/ZYSOCKET 更新 4.3.5更新说明: 修复各种BUG. 重写了一份 protobuf-net 有什么用呢,不需 ...