正确处理listview的position
来源:互联网 发布:商为开店软件 编辑:程序博客网 时间:2024/05/19 04:27
当ListView包含有HeaderView或FooterView时,传入getView或者onItemClick的position是怎样的,这是个值得探讨的问题
先列出错误的用法
定义:
错误用法一:
错误用法二:
当ListView没有包含HeaderView和FooterView的时候,上面的用法没有问题,一旦包含,那么获取的数据项可能不准。因为此时传入的position是包含了HeaderView和FooterView的索引的:
如果按照上面的方式编码,则点击列表中的任意一项,获取的数据项始终是position-1项。即这里的position其实是一个包含了HeaderViews和FooterViews,以及我们的DataList的大List中的索引。
那么正确获取数据项的方法是:
当然你可以用判断position==0,但是如果包含有多个HeaderView或者FooterView,这样判断既麻烦也容易出错。按照上面的方法做,无需关心position值是什么,都可以正确获取数据项,Android已经帮我们处理了所有的情况。
看起来AdapterView.getAdapter().getItem()与Adapter.getItem()没什么不同,但实际上,当ListView包含了HeaderView的时候,AdapterView.getAdapter()获取的Adapter不是我们定义的Adapter。
为了避免下面各种adapter的混淆,命名我们的adapter为myAdapter。
来看下ListView.setAdapter的源码,看一下Android对我们的myAdapter做了什么:
可以很清楚的看到,当调用ListView.setAdapter的时候,会先判断是否已经包含了HeaderView和FooterView,如果包含,则ListView新建一个包装类HeaderViewListAdapter,包含myAdapter,然后ListView内部的另一个adapter引用(AbsListView.mAdapter)指向这个对象,myAdapter并没有被真的改变。
那么当ListView包含了HeaderView的时候,调用的getItem方法又有什么不同?来看看HeaderViewListAdapter.getItem(),源码如下:
该方法对position的各种情况做了判断,如果包含有HeaderViews,则会先从position减掉HeaderView的size。看这一句:
这里的mAdapter,通过构造函数HeaderViewListAdapter赋值,结合ListView.setAdapter()源码可以知道就是myAdapter,所以此时的mAdapter.getItem=myAdapter.getItem,传入的position范围是0~DataList.size()。
需要注意的是AdapterView.getCount()返回的数据是包含有HeaderView和FooterView的个数的:
那么,在myAdapter中的getView,以及getItem传入的position为什么没有受到影响呢?原因是类似的。
ListView最终在渲染item布局的时候(具体流程不在这里解释),会调用mAdapter.getView,此处的mAdapter,包含HeaderView的时候是HeaderViewListAdapter,所以还是直接看HeaderViewListAdapter.getView的源码:
对于position的处理同getItem(),所以原因也很明了了。
了解了position与HeaderView之间的关系后,在编写这部分代码的时候就应当特别注意一点:addHeaderView与addFooterView必须在setAdapter之前被调用。因为setAdapter中要对headers和footers做判断的!
不过即使你粗心了,Android也抛异常会提醒你:
Caused by: java.lang.IllegalStateException: Cannot add header view to list — setAdapter has already been called.
- 正确处理listview的position
- 正确处理listview的position
- 正确处理listview的position
- listView的真实position
- listView的position问题
- ListView的position含义
- ListView的position的保持
- ListView的position的保持
- ListView的position的保持
- ListView的position的保持
- ListView 的position和id的区别
- 正确处理SqlCeException的方法
- 对InterruptedException的正确处理
- ListView有Header时的position情况
- ListView添加Header后position的计算
- ListView有Header时的position情况
- ListView设置选中指定的条目无效,listView.setSelection(position);
- PHP magic_quotes_gpc的正确处理方式
- http协议详解
- gcd多线程查看是否执行完毕dispatch_barrier_async
- 合并果子
- Spring7大模块
- spring+springMVC+mybatis整合示例(基于XML配置文件)
- 正确处理listview的position
- .netCoreMVC添加数据仓储
- Python 函数参数传递方式
- Android 控制屏幕唤醒常亮或熄灭
- RCF
- Codeforces 834C The Meaningless Game【思维】
- 父元素没设置高度子元素自适应高度
- Nginx反向代理以及缓存
- hdu1198 dfs