Android視圖大小測量案例研究
最近我的同事遇到了一個很有趣的問題。下面這個非常簡單的布局會向我們展示一些關于Android測量系統的有趣發現。
- <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>
預期的運行結果,應該顯示帶顏色背景的文本。但實際上,你根本就看不到背景ImageView:
問題的根源就在于測量。因為我們使用了顏色來代替了圖片,所以ImageView很自然地認為它的寬和高都是零。Colors(或者ColorDrawables)并沒有像圖片那樣具有實質意義上的大小,而ImageView不會大于它的背景或者圖片源的大小。
有意思的是,我們可以想出很多方法來解決這個問題。每個解決方法都揭示了測量系統的某個新的方面。從直觀的角度依次了解:
- 將父布局FrameLayout設置為match_parent。這樣,ImageView就可以知道具體的大小,以此充滿父視圖。
- 使用View代替ImageView。View會擴張并填充空間,而ImageView不會。
- 使用RelativeLayout代替FrameLayout。相對布局在測量子視圖大小時,會采用不同的方式。
- 為TextView寬或高設置為match_parent。這是個很讓人困惑的方法。它之所以有效,是因為如果FrameLayout有一個或多個子視圖使用了match_parent,會再做一次測量。
理解而不是簡單地解決這個問題,需要反復閱讀FrameLayout.onMeasure()和ImageView.onMeasure()代碼。面對這樣的問題,Android是開源項目這一事實讓我感到非常高興。
這個問題的核心在于,僅僅展示顏色不應該使用ImageView,用一個帶背景的View會更加可靠。
很顯然,上面的布局沒有什么實質意義,大家一般都會給TextView設置背景。不過,這是一種說明問題的簡單方式。
原文鏈接: danlew