之前 遇到ScrollView中嵌入ListView,GridView衝突的解決(讓ListView全顯示出來) 鏈接
網上查找資料,代碼大致如下:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class ListViewMeasur extends ListView {
public ListViewMeasur(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListViewMeasur(Context context) {
super(context);
}
public ListViewMeasur(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
其中對這段代碼有疑惑:
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
網上也有解釋的文章 比如鏈接 文章對 測量模式模式的講解十分詳細,但是本文通過源碼來進一步理解。
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
作爲參數onMeasure()方法,很明顯作爲代表測量的高度
super.onMeasure(widthMeasureSpec, expandSpec);
那接下來通過源碼看一下調用的suMeasureSpec.makeMeasureSpec()方法。
public static int makeMeasureSpec(int size, int mode) {
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
return (size & ~MODE_MASK) | (mode & MODE_MASK);
}
}
MeasureSpec是一個32位的int值,其中高2位代表測量模式,低30位代表測量大小。
在makeMeasureSpec中看大 return size + mode; 現在通過一段代碼模擬一下這個過程。
模擬makeMeasureSpec 輸出的是10011111111111111111111111111111
最高兩位是10的時候表示"最大模式"。即MeasureSpec.AT_MOST
public class URShift {
private static final int MODE_SHIFT = 30;
public static final int AT_MOST = 2 << MODE_SHIFT;
public static void main(String[] args) {
int i =Integer.MAX_VALUE ;
System.out.println(Integer.toBinaryString(i));
//~1111111111111111111111111111111
System.out.println(Integer.toBinaryString(makeMeasureSpec(Integer.MAX_VALUE >> 2,
AT_MOST)));
//~10011111111111111111111111111111
}
public static int makeMeasureSpec(int size, int mode) {
return size + mode;
}
}
其實MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST)就是生成一個符合MeasureSpec的一個32位的包含測量模式和測量高度的int值。
我是IT小王,如果喜歡我的文章,可以掃碼關注我的微信公衆號