開發(fā)中經(jīng)常遇到各種較為復(fù)雜的界面误辑,有Listview的頭布局也是listview沧踏,嵌套ListView、ScrollView等巾钉,這些布局使用過(guò)程中經(jīng)常會(huì)出現(xiàn)一個(gè)問(wèn)題就是布局顯示不全翘狱。今天就以解決listview的頭布局也是listview時(shí)頭布局顯示不全時(shí)的解決方法做個(gè)筆記
問(wèn)題:使用中發(fā)現(xiàn)listview的頭布局也是listview時(shí)雖然在XML文件中設(shè)置了高為
match_parent
但卻還是只展示了第一行
解決方法:自定義Listview重寫onMeasure方法
public class ExpandListView extends ListView {
public ExpandListView(Context context) {
super(context);
}
public ExpandListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ExpandListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2
, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
關(guān)鍵代碼
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2 , MeasureSpec.AT_MOST);
-
首先看
MeasureSpec
,對(duì)自定義view有了解的話對(duì)他就應(yīng)該不陌生,在自定義view中我們知道重寫onMeasure測(cè)量view大小時(shí)砰苍,提供了三種測(cè)量模式潦匈。- MeasureSpec.EXACTLY:精確模式(在這種模式下,尺寸的值是多少赚导,那么這個(gè)組件的長(zhǎng)或?qū)捑褪嵌嗌佟?
- MeasureSpec.AT_MOST:最大值模式(就是父組件茬缩,能夠給出的最大的空間,當(dāng)前組件的長(zhǎng)或?qū)捵畲笾荒転檫@么大,當(dāng)然也可以比這個(gè)小)。
- MeasureSpec.UNSPECIFIED:未指定模式(父布局沒(méi)有給子布局強(qiáng)加任何約束哮内,子布局想要多大就要多大).
-
分析MeasureSpec這個(gè)源碼時(shí)可以看到里面主要提供了4個(gè)方法
-
public static int makeMeasureSpec(int size, int mode)
:這個(gè)是由我們給出的尺寸大小和模式生成一個(gè)包含這兩個(gè)信息的int變量,這里的這個(gè)mode參數(shù)掂为,傳上面三個(gè)常量中的一個(gè)。 -
public static int getMode(int measureSpec)
:這個(gè)是得到這個(gè)變量中表示的模式信息员串,將得到的值與三個(gè)常量進(jìn)行比較勇哗。 -
public static int getSize(int measureSpec)
:這個(gè)是得到這個(gè)變量中表示的尺寸大小的值 -
public static String toString(int measureSpec)
:把這個(gè)變量里面的模式和大小組成字符串返回來(lái),方便打日志
-
參數(shù)Integer.MAX_VALUE >> 2何解寸齐?
在Android里面欲诺,一個(gè)控件所占的模式和大小是通過(guò)一個(gè)整數(shù)int來(lái)表示的抄谐,一個(gè)int類型我們知道有32 位。
- 最高兩位是00的時(shí)候表示"未指定模式"扰法。即MeasureSpec.UNSPECIFIED
- 最高兩位是01的時(shí)候表示"'精確模式"蛹含。即MeasureSpec.EXACTLY
- 最高兩位是11的時(shí)候表示"最大模式"。即MeasureSpec.AT_MOST
回頭看我們的關(guān)鍵代碼
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2
, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
- 調(diào)用了MeasureSpec類中的makeMeasureSpec方法塞颁,這個(gè)方法是用來(lái)生成一個(gè)帶有模式和大小信息的int值的挣惰。第一個(gè)參數(shù)Integer.MAX_VALUE >> 2,是傳的一個(gè)大小值殴边,我們先取Integer.MAX_VALUE來(lái)獲取int值的最大值,然后左移2位就得到這個(gè)臨界值最大值了 珍语。這樣不管我們的Listview,GridView等有多少數(shù)據(jù)都能展示出來(lái)了锤岸。
效果圖