亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android ListView position詳解及實(shí)例代碼

 更新時(shí)間:2016年10月14日 15:52:27   投稿:lqh  
這篇文章主要介紹了Android ListView position的相關(guān)資料,在開(kāi)發(fā)Android 應(yīng)用的時(shí)候你真的用對(duì)了嗎?這里給大家徹底解釋下,需要的朋友可以參考下

 我們?cè)谑褂肔istView的時(shí)候,一般都會(huì)為L(zhǎng)istView添加一個(gè)響應(yīng)事件android.widget.AdapterView.OnItemClickListener。對(duì)OnItemClickListener的position和id參數(shù),我相信有些人在這上面走了些彎路。

    在使用listview的時(shí)候,我們經(jīng)常會(huì)在listview的監(jiān)聽(tīng)事件中,例如OnItemClickListener(onItemClick)中,或listview的adapter中(getView、getItem、getItemId等)看到position這個(gè)變量。在我們沒(méi)有為listview添加headerView時(shí),position和數(shù)據(jù)源集合的索引是一致的,當(dāng)添加了headerView之后,某些地方的position值就會(huì)發(fā)生變化,如果不理解清楚,經(jīng)常會(huì)犯一些糊涂。

  在listview添加了headerView后, 會(huì)將所有view交給HeaderViewListAdapter來(lái)處理,所以我們要在setAdapter之前添加headerView或footerView,否則將顯示不出來(lái)。

@Override
  public 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中幾個(gè)帶position參數(shù)的方法實(shí)現(xiàn),我們可以看到在傳出的position為adjPosition,而adjPosition均為我們自動(dòng)去掉了headerView的數(shù)量,所以adapter中幾個(gè)帶position變量的方法,得到的position值均和數(shù)據(jù)源集合索引一致,仔細(xì)翻看HeaderListAdapter中所有需要傳出position的方法,position的值都是自動(dòng)減去了headerView數(shù)量。

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;
    }

    // Adapter
    final 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;
    }

    // Adapter
    final 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;
  }

 

  我們?cè)賮?lái)分析分析OnItemClickListener的相關(guān)源碼,OnItemClickListener在android.widget.AdapterView的public boolean performItemClick(View view, int position, long id)函數(shù)中被調(diào)用。而performItemClick是在android.widget.AbsListView.PerformClick.run() 中被調(diào)用:

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 happen
      if (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 click
        if (view != null) {
          performItemClick(view, motionPosition, adapter.getItemId(motionPosition));
        }
      }
    }
  }

  從源碼中,我們可以看到position對(duì)應(yīng)motionPosition,而motionPosition通過(guò)調(diào)試,我們發(fā)現(xiàn)就是listview中被點(diǎn)擊的位置,所以我們經(jīng)常在onItemClick中需要獲取數(shù)據(jù)源集合中某個(gè)item時(shí),會(huì)習(xí)慣性寫(xiě)這樣代碼:sourceList.get(position-listView.getHeaderViewsCount())。

  我們發(fā)現(xiàn)onItemClick還有一個(gè)參數(shù),其實(shí)就是上面源碼中傳遞給performItemClick的第三個(gè)參數(shù),而第三個(gè)參數(shù)是通過(guò)調(diào)用adapter的getItemId將motionPosition減去了headerView的數(shù)量,所以這個(gè)參數(shù)的結(jié)果是與數(shù)據(jù)源集合的索引一致的。也就是說(shuō),我們完全可以使用onItemClick的id這個(gè)參數(shù),這個(gè)參數(shù)是和數(shù)據(jù)源集合的索引一致的。

  另外我們需要注意,如果數(shù)據(jù)源沒(méi)有內(nèi)容,則id的值會(huì)為-1,所以我們?cè)谑褂胕d時(shí),需要對(duì)id做適當(dāng)判斷。

  總結(jié):在OnItemClickListener的onItemClick方法中,當(dāng)我們需要獲取點(diǎn)擊listview對(duì)應(yīng)的數(shù)據(jù)源索引時(shí),使用id參數(shù)即可。另外除了onItemClick的position參數(shù)是點(diǎn)擊listview對(duì)應(yīng)view的位置外,adapter中所有position均為數(shù)據(jù)源索引位置。其實(shí)換個(gè)角度更容易記,在listview中,position理應(yīng)是listview中view對(duì)應(yīng)的位置,而在adapter中,理應(yīng)是數(shù)據(jù)源的索引位置。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

最新評(píng)論