码迷,mamicode.com
首页 > 移动开发 > 详细

Android MeasuerSpce的由来及使用

时间:2016-04-06 13:35:51      阅读:280      评论:0      收藏:0      [点我收藏+]

标签:

含义:MeasuerSpce是parent传递给child的一组测量值(size)和模式(mode)的组合。

使用场景:经常我们会在child的onMeasure(int widthMeasureSpec,int heightMeasureSpec)这个函数中来对spec进行处理,用于确定child的长和宽。

技术分享

这里我们看到MeasureSpec有3中测量模式:

MeasureSpec.AT_MOST :child最多达到parent的大小,这一类通常归于"wrap_content"。

MeasureSpec.EXACTLY:child的大小是一个确定的值,这一类通常归于"match_parent"或者是一个确定的值。

MeasureSpec.UNSPECIFED:这个几乎不用,未指定,child可以得到自己想要的任何大小。

Measure的makeMeasureSpec,getMode,getSize我这里就不多说了,很简单就是一个位运算。


说了半天,到底这个widthMeasureSpec和heightMeasureSpec怎么来的呢?这就需要看看源码。

我们知道View的测量和绘制都是通过它的parent来触发的,所以直接进ViewGroup

切入点就是measure:

技术分享

这里我们又看到一个parentWidthMeasureSpec和parentHeightSpec,这里我们先不管,大概知道这个是它的parent给它的spec。

继续进入函数:

技术分享

可以看到,这里在switch(mode)和我们处理view的onMeasure差不多。

继续向下:

技术分享

到这里,spec就已经组合好了,下一步应该是传递给child计算了。技术分享

技术分享

到这里为止,viewgroup的测量就算完成了。接下来就是交给child自己计算,也就回到了,我们最初的onMeasure函数中。

上面我们还说到了这个parentWidthMeasureSpec和parentHeightSpec,其实也就是当前viewgroup的parent给它的测量模式和值。遵循上面的步骤,一模一样。


所以以后像遇到这个问题,解决思路和办法就很简单了。

View view=getLayoutInflater().inflate(R.layout.layout_item, null);

Toast.makeText(MainActivity.this, "view_w="+view.getMeasuredWidth()+","+view.getLayoutParams(), 0).show();

技术分享

为啥view的宽度为0,layoutparams为null?

view的宽度为0,很明显:就是view没有measure,因为我们是从一个xml文件中pull解析出来的一个view,它没有parent更没有parent测量,所以为0.

解决办法就是measure,view.measure(0,0)一下;我们传0,0,最终也就是view自己测量自己。这里还有一个layoutparams为null,为啥呢?

我们知道layoutParams是parent给child的布局参数。在view的源码中我们看到

技术分享

还有get,set方法

技术分享

我们回到viewGroup中。


技术分享

这里我们看到addview会传递一个params,这个params怎么来的呢?

技术分享

这里我们看到了child的layoutparams是在addview中赋值的,所以上面的layoutinflate的view因为没有parent所以就没有layoutparams。

解决办法:

技术分享

欢迎大家指正和批评!



Android MeasuerSpce的由来及使用

标签:

原文地址:http://blog.csdn.net/campl/article/details/51072667

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!