編輯:關於android開發
含義: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。
解決辦法:
歡迎大家指正和批評!
如何避免TCP的TIME_WAIT狀態如何避免TCP的TIME_WAIT狀態——lvyilong316關於TCP連接的TIME-WAIT狀態,它是為何而生,存在的意義是什
The Genymotion Virtual device could not obtain an IP address解決辦法,genymotionobtain打開Ge
Android應用ViewDragHelper詳解及部分源碼淺析 1 背景 很久沒有更新博客了,忙裡偷閒產出一篇。寫這片文章主要是去年項目中的一個需求,
Android性能優化之使用線程池處理異步任務 說到線程,我想大家都不陌生,因為在開發時候或多或少都會用到線程,而通常創建線程有兩種方式: 1、繼承Thread類