ListView position
在使用listview的時候,我們經常會在listview的監聽事件中,例如OnItemClickListener(onItemClick)中,或listview的adapter中(getView、getItem、getItemId等)看到position這個變量。在我們沒有為listview添加headerView時,position和數據源集合的索引是一致的,當添加了headerView之后,某些地方的position值就會發生變化,如果不理解清楚,經常會犯一些糊涂。
在listview添加了headerView后, 會將所有view交給HeaderViewListAdapter來處理,所以我們要在setAdapter之前添加headerView或footerView,否則將顯示不出來。
@Overridepublic void setAdapter(ListAdapter adapter) {if (mAdapter != null && mDataSetObserver != null) {mAdapter.unregisterDataSetObserver(mDataSetObserver);}resetList();mRecycler.clear();if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);} else {mAdapter = adapter;}先看看HeaderListAdapter中幾個帶position參數的方法實現,我們可以看到在傳出的position為adjPosition,而adjPosition均為我們自動去掉了headerView的數量,所以adapter中幾個帶position變量的方法,得到的position值均和數據源集合索引一致,仔細翻看HeaderListAdapter中所有需要傳出position的方法,position的值都是自動減去了headerView數量。
public View getView(int position, View convertView, ViewGroup parent) {// Header (negative positions will throw an ArrayIndexOutOfBoundsException)int numHeaders = getHeadersCount();if (position < numHeaders) {return mHeaderViewInfos.get(position).view;}// Adapterfinal int adjPosition = position - numHeaders;int adapterCount = 0;if (mAdapter != null) {adapterCount = mAdapter.getCount();if (adjPosition < adapterCount) {return mAdapter.getView(adjPosition, convertView, parent);}}// Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)return mFooterViewInfos.get(adjPosition - adapterCount).view;} public Object getItem(int position) {// Header (negative positions will throw an ArrayIndexOutOfBoundsException)int numHeaders = getHeadersCount();if (position < numHeaders) {return mHeaderViewInfos.get(position).data;}// Adapterfinal int adjPosition = position - numHeaders;int adapterCount = 0;if (mAdapter != null) {adapterCount = mAdapter.getCount();if (adjPosition < adapterCount) {return mAdapter.getItem(adjPosition);}}// Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)return mFooterViewInfos.get(adjPosition - adapterCount).data;}public long getItemId(int position) {int numHeaders = getHeadersCount();if (mAdapter != null && position >= numHeaders) {int adjPosition = position - numHeaders;int adapterCount = mAdapter.getCount();if (adjPosition < adapterCount) {return mAdapter.getItemId(adjPosition);}}return -1;}
我們再來分析分析OnItemClickListener的相關源碼,OnItemClickListener在android.widget.AdapterView的public boolean performItemClick(View view, int position, long id)函數中被調用。而performItemClick是在android.widget.AbsListView.PerformClick.run() 中被調用:
private class PerformClick extends WindowRunnnable implements Runnable {int mClickMotionPosition;public void run() {// The data has changed since we posted this action in the event queue,// bail out before bad things happenif (mDataChanged) return;final ListAdapter adapter = mAdapter;final int motionPosition = mClickMotionPosition;if (adapter != null && mItemCount > 0 &&motionPosition != INVALID_POSITION &&motionPosition < adapter.getCount() && sameWindow()) {final View view = getChildAt(motionPosition - mFirstPosition);// If there is no view, something bad happened (the view scrolled off the// screen, etc.) and we should cancel the clickif (view != null) {performItemClick(view, motionPosition, adapter.getItemId(motionPosition));}}}}從源碼中,我們可以看到position對應motionPosition,而motionPosition通過調試,我們發現就是listview中被點擊的位置,所以我們經常在onItemClick中需要獲取數據源集合中某個item時,會習慣性寫這樣代碼:sourceList.get(position-listView.getHeaderViewsCount())。
我們發現onItemClick還有一個參數,其實就是上面源碼中傳遞給performItemClick的第三個參數,而第三個參數是通過調用adapter的getItemId將motionPosition減去了headerView的數量,所以這個參數的結果是與數據源集合的索引一致的。也就是說,我們完全可以使用onItemClick的id這個參數,這個參數是和數據源集合的索引一致的。
另外我們需要注意,如果數據源沒有內容,則id的值會為-1,所以我們在使用id時,需要對id做適當判斷。
總結:在OnItemClickListener的onItemClick方法中,當我們需要獲取點擊listview對應的數據源索引時,使用id參數即可。另外除了onItemClick的position參數是點擊listview對應view的位置外,adapter中所有position均為數據源索引位置。其實換個角度更容易記,在listview中,position理應是listview中view對應的位置,而在adapter中,理應是數據源的索引位置。
轉載于:https://www.cnblogs.com/endure/p/5872409.html
總結
以上是生活随笔為你收集整理的ListView position的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows server 2008
- 下一篇: 【设计模式之单例模式InJava】