View类的onMeasure方法介绍

除非你总是需要一个100×100像素的控件,否则,你必须要重写onMeasure。 

onMeasure方法在控件的父元素正要放置它的子控件时调用。它会问一个问题,“你想要用多大地方啊?”,然后传入两个参数——widthMeasureSpec和heightMeasureSpec。 
它们指明控件可获得的空间以及关于这个空间描述的元数据。
 

比返回一个结果要好的方法是你传递View的高度和宽度到setMeasuredDimension方法里。 
接下来的代码片段给出了如何重写onMeasure。注意,调用的本地空方法是来计算高度和宽度的。它们会译解widthHeightSpec和heightMeasureSpec值,并计算出合适的高度和宽度值。 

Java代码   收藏代码
  1. @Override  
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  3.   
  4. int measuredHeight = measureHeight(heightMeasureSpec);  
  5.   
  6. int measuredWidth = measureWidth(widthMeasureSpec);  
  7.   
  8. setMeasuredDimension(measuredHeight, measuredWidth);  
  9.   
  10. }  
  11.   
  12. private int measureHeight(int measureSpec) {  
  13.   
  14. // Return measured widget height.  
  15.   
  16. }  
  17.   
  18. private int measureWidth(int measureSpec) {  
  19.   
  20. // Return measured widget width.  
  21.   
  22. }  


边界参数——widthMeasureSpec和heightMeasureSpec ,效率的原因以整数的方式传入。在它们使用之前,首先要做的是使用MeasureSpec类的静态方法getMode和getSize来译解,如下面的片段所示: 

Java代码   收藏代码
  1. int specMode = MeasureSpec.getMode(measureSpec);  
  2. int specSize = MeasureSpec.getSize(measureSpec);  


依据specMode的值,如果是AT_MOST,specSize 代表的是最大可获得的空间;如果是EXACTLY,specSize 代表的是精确的尺寸;如果是UNSPECIFIED,对于控件尺寸来说,没有任何参考意义。 

当以EXACT方式标记测量尺寸,父元素会坚持在一个指定的精确尺寸区域放置View。在父元素问子元素要多大空间时,AT_MOST指示者会说给我最大的范围。在很多情况下,你得到的值都是相同的。 

在两种情况下,你必须绝对的处理这些限制。在一些情况下,它可能会返回超出这些限制的尺寸,在这种情况下,你可以让父元素选择如何对待超出的View,使用裁剪还是滚动等技术。 

接下来的框架代码给出了处理View测量的典型实现: 


Java代码   收藏代码
  1. @Override  
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  3.   
  4. int measuredHeight = measureHeight(heightMeasureSpec);  
  5.   
  6. int measuredWidth = measureWidth(widthMeasureSpec);  
  7.   
  8. setMeasuredDimension(measuredHeight, measuredWidth);  
  9.   
  10. }  
  11.   
  12. private int measureHeight(int measureSpec) {  
  13.   
  14. int specMode = MeasureSpec.getMode(measureSpec);  
  15. int specSize = MeasureSpec.getSize(measureSpec);  
  16.   
  17. // Default size if no limits are specified.  
  18.   
  19. int result = 500;  
  20.   
  21. if (specMode == MeasureSpec.AT_MOST)   
  22.   
  23. {  
  24.   
  25. // Calculate the ideal size of your  
  26.   
  27. // control within this maximum size.  
  28.   
  29. // If your control fills the available  
  30.   
  31. // space return the outer bound.  
  32.   
  33. result = specSize;  
  34.   
  35. }   
  36.   
  37. else if (specMode == MeasureSpec.EXACTLY)   
  38.   
  39. {  
  40.   
  41. // If your control can fit within these bounds return that value.  
  42.   
  43. result = specSize;  
  44.   
  45. }  
  46.   
  47. return result;  
  48.   
  49. }  
  50.   
  51. private int measureWidth(int measureSpec) {  
  52.   
  53. int specMode = MeasureSpec.getMode(measureSpec);  
  54. int specSize = MeasureSpec.getSize(measureSpec);  
  55.   
  56. // Default size if no limits are specified.  
  57.   
  58. int result = 500;  
  59.   
  60. if (specMode == MeasureSpec.AT_MOST)  
  61.   
  62. {  
  63.   
  64. // Calculate the ideal size of your control  
  65.   
  66. // within this maximum size.  
  67.   
  68. // If your control fills the available space  
  69.   
  70. // return the outer bound.  
  71.   
  72. result = specSize;  
  73.   
  74. }   
  75.   
  76. else if (specMode == MeasureSpec.EXACTLY)   
  77.   
  78. {  
  79.   
  80. // If your control can fit within these bounds return that value.  
  81.   
  82. result = specSize;  
  83.   
  84. }  
  85.   
  86. return result;  
  87.   
  88. }  
其他参考:
Android中的View.onMeasure() 
http://blog.sina.com.cn/s/blog_4b650d650100nrhr.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值