今天突然發現ListView的OnItemClickListener監聽事件中的position返回是從1開始的,一直覺得很奇怪,在羣裏問了後,可能是headerView的問題,特意去查了一番,原來是如此:
特此記過!
(1)添加HeaderView之後尺寸佈局被忽略。
通常添加頭部的方法是
1
2
3
|
LayoutInflater
lif = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View
headerView = lif.inflate(R.layout.header, null ); mListView.addHeaderView(headerView); |
原因:
lif.inflate(R.layout.header, null)丟失了XML佈局中根View的LayoutParam,應該使用的是
1
|
lif.inflate(R.layout.header,
mListView, false ); |
(2)添加HeaderView之後導致OnItemClickListener的position移位
OnItemClickListener接口的方法:
1
|
void onItemClick(AdapterView<?>
parent, View view, int position,
long id) |
position通常是從0開始的,但是添加了HeaderView之後,position也會將HeaderView的數目計算進去。
幾個解決辦法:
1,手動計算真實的position位置:
1
2
3
4
5
6
7
8
|
final headerCount
= 1 ; mListView.setOnItemClickListener( new OnItemClickListener()
{ @Override public void
onItemClick(AdapterView<?> parent, View view, int position,
long id)
{ Item
item = myAdapter.getItem(position - headerCount); } }); |
2,其實上面的步驟ListView已經爲我們提供了,所以可以改寫爲:
1
2
3
4
5
6
7
|
mListView.setOnItemClickListener( new OnItemClickListener()
{ @Override public void
onItemClick(AdapterView<?> parent, View view, int position,
long id)
{ Item
item = parent.getAdapter().getItem(position); } }); |
當有headerView被添加時,實際傳遞給ListView的adapter被包裝,parent.getAdapter()返回真實被ListView使用的Adapter(HeaderViewListAdapter),HeaderViewListAdapter的getItem(int)方法處理了position的問題。
(3)LayoutInflater的infalte()
用來呼應第一個問題。LayoutInflater的作用很簡單,就是將XML的佈局文件“翻譯”成相應的View對象,而且出於性能的考慮,LayoutInflater只能處理編譯後的XML文件,而不能處理通常明文編碼的XML文件。最常用的一個方法:
1
|
View
inflate( int resource,
ViewGroup root, boolean attachToRoot) |
其中:
resource是佈局文件ID
root是父ViewGroup對象,
attachToRoot是是否將“翻譯”出來的View添加到上面的root中
root和attachToRoot是共同作用的:
1,有root,同時attachToRoot爲false,那麼inflate()返回的就是“翻譯”得到的view
2,有root,同時attachToRoot爲true,那麼inflate()就是將“翻譯”得到的view添加到root後,然後返回root
3,無root,同時attachToRoot爲false,那麼inflate()返回的就是“翻譯”得到的view。
4,無root,同時attachToRoot爲true,報錯。
另外,root還有一個重要的作用就是爲“翻譯”得到的view添加合適的LayoutParam,並且如果並不想將得到的View添加到root的話,傳遞何種root是並沒有要求的,比如:
1
2
3
|
View
view = mLayoutInflater.inflate(R.layout.header, new ListView(mContext),
false ); View
view = mLayoutInflater.inflate(R.layout.header, new LinearLayout(mContext),
false ); View
view = mLayoutInflater.inflate(R.layout.header, new RelativeLayout(mContext),
false ); |