Android ListView position详解及实例代码

Android ListView position详解及实例代码,第1张

概述 我们在使用ListView的时候,一般都会为ListView添加一个响应事件android.widget.AdapterView.OnItemClickListener。对OnItemClickListener的position和id参数,我相信有些人在这上面走了些弯路。

 我们在使用ListVIEw的时候,一般都会为ListVIEw添加一个响应事件androID.Widget.AdapterVIEw.OnItemClickListener。对OnItemClickListener的position和ID参数,我相信有些人在这上面走了些弯路。

    在使用ListvIEw的时候,我们经常会在ListvIEw的监听事件中,例如OnItemClickListener(onItemClick)中,或ListvIEw的adapter中(getVIEw、getItem、getItemID等)看到position这个变量。在我们没有为ListvIEw添加headerVIEw时,position和数据源集合的索引是一致的,当添加了headerVIEw之后,某些地方的position值就会发生变化,如果不理解清楚,经常会犯一些糊涂。

  在ListvIEw添加了headerVIEw后, 会将所有vIEw交给headerVIEwlistadapter来处理,所以我们要在setAdapter之前添加headerVIEw或footerVIEw,否则将显示不出来。

@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中几个带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;    }    // 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;  }
 

  我们再来分析分析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 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对应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中,理应是数据源的索引位置。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

总结

以上是内存溢出为你收集整理的Android ListView position详解实例代码全部内容,希望文章能够帮你解决Android ListView position详解及实例代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147995.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存