前面的文章 我留下了一個疑惑,那就是到底爲何 NestedScrollView
要把子 View 的測量模式強行設置爲 MeasureSpec.UNSPECIFIED
,這不,在鴻洋的 "wanAndroid" 中,他再次提出了這樣的問題:app
MesureSpec.UNSPECIFIEDthis
- 這個模式何時會遇到?
- 遇到後怎麼處理?
- 有什麼注意事項?
下面摘自用戶「陳小緣啦啦啦」的回答,我以爲回答的很是到位,特別在這裏和你們分享一下。code
UNSPECIFID
,就是未指定的意思,在這個模式下父控件不會干涉子 View 想要多大的尺寸。
那麼,這個模式何時會onMeasure()
裏遇到呢?實際上是取決於它的父容器。
就拿最經常使用的 RecyclerView
作例子,在 Item
進行 measure()
時,若是列表可滾動,而且 Item
的寬或高設置了 wrap_content
的話,那麼接下來,itemView 的 onMeasure( )
方法的測量模式就會變成 MeasureSpec.UNSPECIFIED
。
咱們不妨打開 RecyclerView
源碼,會在 getChildMeasureSpec()
方法裏看到這麼一句註釋:圖片
MATCH_PARENT can't be applied since we can scroll in this dimension, wrap instead using UNSPECIFIED.ci
它想表達的是:在可滾動的ViewGroup
中,不該該限制 Item 的尺寸(若是是水平滾動,就不限制寬度),爲何呢? 由於是能夠滾動的,就算 Item 有多寬,有多高,經過滾動也同樣能看到滾動前被遮擋的部分。get
這裏其實也就回答了我以前詢問的
NestedScrollView
要強行設置 Item 爲 UNSPECIFIED 的緣由。
有同窗可能會有疑問: 我設置wrap_content
,在onMeasure()
中應該收到的是AT_MOST
纔對啊,爲何要強制變成UNSPECIFIED
?源碼
這是由於考慮到 Item 的尺寸有可能超出這個可滾動的 ViewGroup
的尺寸,而在 AT_MOST
模式下,你的尺寸不能超出你所在的 ViewGroup
的尺寸,最多隻能等於,因此用 UNSPECIFIED
會更合適,這個模式下你想要多大就多大。it
那麼,咱們在自定義 View 的時候,在測量時發現是 UNSPECIFIED
模式時,應該怎麼作呢?io
這個就比較自由了,既然尺寸由本身決定,那麼我能夠寫死爲 50,也能夠固定爲 200。但仍是建議結合實際需求來定義咯。容器
好比 ImageView
,它的作法就是:有設置圖片內容(drawable)的話,會直接使用這個 drawable 的尺寸,但不會超過指定的 MaxWidth
或 MaxHeight
, 沒有內容的話就是 0。而 TextView
處理 UNSPECIFIED
的方式,和 AT_MOST
是同樣的。
固然了,這些尺寸都不必定等於最後 layout
出來的尺寸,由於最後決定子 View
位置和大小的,是在 onLayout()
方法中,在這裏你徹底能夠無視這些尺寸,去 layout()
成本身想要的樣子。不過,通常不會這麼作。