android listview 在添加header时候 OnItemClickListener position 索引不正确
来源:互联网 发布:淘宝名不虚传软件 编辑:程序博客网 时间:2024/05/23 12:00
在使用ListView添加如下代码时 listview.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View arg1, int position, long id) { //此时有人遇到position不是从0开始 } });
对于上面问题,是因为ListView添加了Head导致的,如果Head添加了一个View从1开始,如果Head添加了两个View,则从2开始,依次类推,那么遇到这样的问题如何解决呢,我们当然可以有办法,可以使用如下语句来获取索引所对应的数据
parent.getAdapter().getItem(position)
当给ListView加了一个HeaderView后(代码如下),我们发现,onItemClick方法里的position
参数的值不是我们所期望的,比如点击ListView的第一行,我们期望的position
是0,可是实际上却是1,也就是说,它是从Header而不是从第一行开始计数的。
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.home); mAdapter = new MyAdapter(this); mListView = (ListView) findViewById(R.id.list); mListView.addHeaderView(getLayoutInflater().inflate(R.layout.list_header)); mListView.setAdapter(mAdapter); mListView.setOnClickListener(this);}@Overridepublic void onItemClick(AdapterView<?> parent, View v, int position, long id) { doSomething(mAdapter.getItem(position));}
Google了下,发现有个老外issue过一个bug,和我遇到的问题一样,不过这个bug被RomainGuy reject掉了,理由是,你用错了,请用getAdapter。这回答的太简洁了,完全没法理解,所以只好又去仔细研究ListView的代码,终于领会他的意思了。把其中addHeaderView和setAdapter方法贴下来
/** * Add a fixed view to appear at the top of the list. If addHeaderView is * called more than once, the views will appear in the order they were * added. Views added using this call can take focus if they want. * <p> * NOTE: Call this before calling setAdapter. This is so ListView can wrap * the supplied cursor with one that that will also account for header * views. * * @param v The view to add. * @param data Data to associate with this view * @param isSelectable whether the item is selectable */public void addHeaderView(View v, Object data, boolean isSelectable) { if (mAdapter != null) { throw new IllegalStateException( "Cannot add header view to list -- setAdapter has already been called."); } FixedViewInfo info = new FixedViewInfo(); info.view = v; info.data = data; info.isSelectable = isSelectable; mHeaderViewInfos.add(info);}/** * Sets the data behind this ListView. * * The adapter passed to this method may be wrapped by a {@link WrapperListAdapter}, * depending on the ListView features currently in use. For instance, adding * headers and/or footers will cause the adapter to be wrapped. * * @param adapter The ListAdapter which is responsible for maintaining the * data backing this list and for producing a view to represent an * item in that data set. * * @see #getAdapter() */@Overridepublic void setAdapter(ListAdapter adapter) { if (null != mAdapter) { mAdapter.unregisterDataSetObserver(mDataSetObserver); } resetList(); mRecycler.clear(); if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) { mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter); } else { mAdapter = adapter; } //其它的一些代码这里省略之...}
从代码和注释里都可以很清楚的得知,addHeaderView
一定要在setAdapter
之前调用,如果不这样做,addHeaderView
会抛出一个异常。Android为什么要这样?这是因为,在setAdapter
的时候,会针对我遇到的这种情况(也就是添加Header后position
不正确的这种情况)做些特殊的处理。setAdapter
在内部判断了当前ListView是否有Header或者Footer,如果没有,就直接使用参数传进来的adapter;如果有,则用一个decorated的HeaderViewListAdapter
来替换参数。这个HeaderViewListAdapter
的使命,就是排除Header和Footer,让position
(当然也包括getItem,getItemId)等方法的position
参数)正确返回。
分析到这里,解决方案就出来了:在onItemClick
不要直接使用我们声明的adapter,而是用ListView里的那个decorated adapter。获取它的方法就是调用parent.getAdapter()
。当然,如果ListView没有Header和Footer,直接使用声明的adapter也没有问题,不过为了避免出错,还是统一使用decorated adapter比较好。
把onItemClick改成下面这样,就可以了
@Overridepublic void onItemClick(AdapterView<?> parent, View v, int position, long id) { doSomething(parent.getAdapter().getItem(position));
- android listview 在添加header时候 OnItemClickListener position 索引不正确
- ListView OnItemClickListener position 索引不正确
- 当为ListView添加Header以后,在onitemClick里面position位置不正确处理策略
- ListView添加Header后,onItemClick里的position不正确
- ListView设置onItemCLickListener监听时获取的position不正确问题
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确。
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- linux内核follow_link分析
- Onvif开发server和client
- 计算多项式
- zookeeper 和 dubbo的使用
- Spark kyro Serialization
- android listview 在添加header时候 OnItemClickListener position 索引不正确
- java io/nio的使用介绍
- 阿里面试准备<android部分>
- Activiti 表单控制的一些感悟
- linux内核capable源代码分析
- Android布局优化之ViewStub、include、merge使用与源码分析
- 各种技术学习地址
- Linux系统信息查看命令
- iOS pushmebaby 常见错误解析