每日一問:詳細說一下 MeasureSpec.UNSPECIFIED

詳細說一下 MeasureSpec.UNSPECIFIED

前面的文章 我留下了一個疑惑,那就是到底爲何 NestedScrollView 要把子 View 的測量模式強行設置爲 MeasureSpec.UNSPECIFIED ,這不,在鴻洋的 "wanAndroid" 中,他再次提出了這樣的問題:app

MesureSpec.UNSPECIFIEDthis

  1. 這個模式何時會遇到?
  2. 遇到後怎麼處理?
  3. 有什麼注意事項?

下面摘自用戶「陳小緣啦啦啦」的回答,我以爲回答的很是到位,特別在這裏和你們分享一下。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 的尺寸,但不會超過指定的 MaxWidthMaxHeight, 沒有內容的話就是 0。而 TextView 處理 UNSPECIFIED 的方式,和 AT_MOST 是同樣的。

固然了,這些尺寸都不必定等於最後 layout 出來的尺寸,由於最後決定子 View 位置和大小的,是在 onLayout() 方法中,在這裏你徹底能夠無視這些尺寸,去 layout()成本身想要的樣子。不過,通常不會這麼作。

相關文章
相關標籤/搜索