Android視圖大小測(cè)量案例研究
最近我的同事遇到了一個(gè)很有趣的問題。下面這個(gè)非常簡(jiǎn)單的布局會(huì)向我們展示一些關(guān)于Android測(cè)量系統(tǒng)的有趣發(fā)現(xiàn)。
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#0F0" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="This is some text." />
- </FrameLayout>
預(yù)期的運(yùn)行結(jié)果,應(yīng)該顯示帶顏色背景的文本。但實(shí)際上,你根本就看不到背景ImageView:
問題的根源就在于測(cè)量。因?yàn)槲覀兪褂昧祟伾珌泶媪藞D片,所以ImageView很自然地認(rèn)為它的寬和高都是零。Colors(或者ColorDrawables)并沒有像圖片那樣具有實(shí)質(zhì)意義上的大小,而ImageView不會(huì)大于它的背景或者圖片源的大小。
有意思的是,我們可以想出很多方法來解決這個(gè)問題。每個(gè)解決方法都揭示了測(cè)量系統(tǒng)的某個(gè)新的方面。從直觀的角度依次了解:
- 將父布局FrameLayout設(shè)置為match_parent。這樣,ImageView就可以知道具體的大小,以此充滿父視圖。
- 使用View代替ImageView。View會(huì)擴(kuò)張并填充空間,而ImageView不會(huì)。
- 使用RelativeLayout代替FrameLayout。相對(duì)布局在測(cè)量子視圖大小時(shí),會(huì)采用不同的方式。
- 為TextView寬或高設(shè)置為match_parent。這是個(gè)很讓人困惑的方法。它之所以有效,是因?yàn)槿绻鸉rameLayout有一個(gè)或多個(gè)子視圖使用了match_parent,會(huì)再做一次測(cè)量。
理解而不是簡(jiǎn)單地解決這個(gè)問題,需要反復(fù)閱讀FrameLayout.onMeasure()和ImageView.onMeasure()代碼。面對(duì)這樣的問題,Android是開源項(xiàng)目這一事實(shí)讓我感到非常高興。
這個(gè)問題的核心在于,僅僅展示顏色不應(yīng)該使用ImageView,用一個(gè)帶背景的View會(huì)更加可靠。
很顯然,上面的布局沒有什么實(shí)質(zhì)意義,大家一般都會(huì)給TextView設(shè)置背景。不過,這是一種說明問題的簡(jiǎn)單方式。
原文鏈接: danlew