标签:
含义: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。
解决办法:
欢迎大家指正和批评!
标签:
原文地址:http://blog.csdn.net/campl/article/details/51072667