我们在使用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详解及实例代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)