ListView的HeaderView


 今天忽然發現ListView的OnItemClickListener監聽事件中的position返回是從1開始的,一直以爲很奇怪,在羣裏問了後,多是headerView的問題,特地去查了一番,原來是如此:java

特此記過!ide

(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 );
上面獲得的View,除了view的LayoutParam分別爲AbsListView.LayoutParams,LinearLayout.LayoutParams,RelativeLayout.LayoutParams以外,內容都一致。 


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

相關文章
相關標籤/搜索