ListView的HeaderView

 今天突然發現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
voidonItemClick(AdapterView<?> parent, View view, intposition, longid)

position通常是從0開始的,但是添加了HeaderView之後,position也會將HeaderView的數目計算進去。 
幾個解決辦法: 
1,手動計算真實的position位置: 
?
1
2
3
4
5
6
7
8
finalheaderCount = 1;
mListView.setOnItemClickListener(newOnItemClickListener() {
    @Override
    publicvoid onItemClick(AdapterView<?> parent, View view,
            intposition, longid) {
        Item item = myAdapter.getItem(position - headerCount);
    }
});

2,其實上面的步驟ListView已經爲我們提供了,所以可以改寫爲: 
?
1
2
3
4
5
6
7
mListView.setOnItemClickListener(newOnItemClickListener() {
    @Override
    publicvoid onItemClick(AdapterView<?> parent, View view,
            intposition, longid) {
        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(intresource, ViewGroup root, booleanattachToRoot)

其中: 
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, newListView(mContext), false);
View view = mLayoutInflater.inflate(R.layout.header, newLinearLayout(mContext), false);
View view = mLayoutInflater.inflate(R.layout.header, newRelativeLayout(mContext), false);
上面得到的View,除了view的LayoutParam分別爲AbsListView.LayoutParams,LinearLayout.LayoutParams,RelativeLayout.LayoutParams之外,內容都一致。 


轉載地址:  http://my.oschina.net/xesam/blog/155542#OSC_h2_1

發佈了36 篇原創文章 · 獲贊 7 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章