Android MeasuerSpce的由来及使用

Posted 裤儿湿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android MeasuerSpce的由来及使用相关的知识,希望对你有一定的参考价值。

含义:MeasuerSpec是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的由来及使用的主要内容,如果未能解决你的问题,请参考以下文章

boolean的由来及使用

Linux的由来及组成

春节由来及元宵节的由来(英文)

深入理解View知识系列三-Window机制Canvas的由来Android事件的由来

深入理解View知识系列三-Window机制Canvas的由来Android事件的由来

交换机的由来及原理