当ListView有Header时,onItemClick里的position不正确
当给ListView加了一个HeaderView后(代码如下),我们发现,onItemClick方法里的position
参数的值不是我们所期望的,比如点击ListView的第一行,我们期望的position
是0,可是实际上却是1,也就是说,它是从Header而不是从第一行开始计数的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Override
protected 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 );
}
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
doSomething(mAdapter.getItem(position));
}
|
Google了下,发现有个老外issue过一个bug,和我遇到的问题一样,不过这个bug被RomainGuy reject掉了,理由是,你用错了,请用getAdapter。这回答的太简洁了,完全没法理解,所以只好又去仔细研究ListView的代码,终于领会他的意思了。把其中addHeaderView和setAdapter方法贴下来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
/**
* 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()
*/
@Override
public 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改成下面这样,就可以了
1
2
3
4
|
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
doSomething(parent.getAdapter().getItem(position));
}
|
本文由Roy最初发表于:http://blog.chengbo.net/2012/03/09/onitemclick-return-wrong-position-when-listview-has-headerview.html,你可以在保持文章完整和保留本声明的情况下转帖、分发和印刷等。
当ListView有Header时,onItemClick里的position不正确相关推荐
- android 解决listview.notifyDataSetChanged刷新时Imageloader加载图片闪烁问题
今天,简单讲讲android里再listview调用notifyDataSetChanged刷新界面时,Imageloader加载图片会闪烁的问题. 最近,发现app里的listview图片会出现闪烁 ...
- android listview 数据同步,android中ListView数据刷新时的同步方法
本文实例讲述了android中ListView数据刷新时的同步方法.分享给大家供大家参考.具体实现方法如下: public class Main extends BaseActivity { priv ...
- Flutter 28: 图解 ListView/GridView 混用时滑动冲突小尝试
小菜在学习过程中会在一个 Page 页面同时用到 GridView 和 ListView 或多个 ListView,此时就会遇到常见的滑动冲突问题.小菜尝试了两种解决滑动冲突的方案,仅记录一下基本的使 ...
- Android listView 去掉header和footer中的分割线
Android listView 去掉header和footer中的分割线 方法一: 在listView中加上android:headerDividersEnabled="false&quo ...
- android listview headerview 分割线,【我的Android进阶之旅】如何去除ListView中Header View、Footer View中的分割线...
最近的项目中给ListView 加入了一个Header View之后,发现Header View的下方也有了分割线,很难看,UI要求将Header View的分割器去掉,好吧.现在就来说一说如何如何去 ...
- 看代码学知识之(2) ListView无数据时显示其他View
看代码学知识之(2) ListView无数据时显示其他View 今天看的一块布局是这样的: <!--The frame layout is here since we will be showi ...
- 如何关闭iPhone打电话时音频里面的Mac选项
下面介绍如何关闭打电话时音频里面的Mac选项 以前点一下是直接可以扬声器 现在每次点击都要选择 恶心 关闭方法: 设置-电话-在其他设备上通话,关闭, 然后重启手机 即可 手机挨近笔记本接打电话,真是 ...
- 用于解决listview嵌套GridView时显示不全的问题。
package com.yetu.ofmy; import android.view.MotionEvent; import android.widget.ListView; /** * * @Cla ...
- MFC的exe启动时提示应用程序配置不正确,应用程序未能启动错误
MFC的exe启动时提示应用程序配置不正确,应用程序未能启动错误 老姐笔记本中毒太深于病入膏肓,无奈迫写一程序"曲线救国".刚启动自己写的程序就出现应用程序配置不正确,应用程序未能 ...
最新文章
- freeswitch 按键采集_《FreeSWITCH 1.2》:支持页面呼叫控制
- LeetCode Minimum Genetic Mutation(dfs,bfs)
- 题目1172:哈夫曼树
- 【数字信号处理】线性时不变系统 LTI “ 输入 “ 与 “ 输出 “ 之间的关系 ( LTI 系统单位脉冲响应 | 卷积 | 卷积推导过程 )
- 【Maven实用技巧】03. Maven 编译打包时如何忽略测试用例
- java 1.8.0 安全_RedHat安全更新修复OpenJDK1.8.0版本漏洞
- 总是记不住java的IO流用法?用N个问题教你掌握java IO流
- php oracle 8.1.7,Oracle 8.1.7在redhat 7.3的安装方法
- C++ Maps 映射
- PHPMailer如何获取企业微信授权码
- 建议Mac M1关闭虚拟内存(交换内存 swap memory)
- java 加权平均_SPSS用加权平均值计算百分位数
- 2021年安全员-C证(陕西省)考试资料及安全员-C证(陕西省)免费试题
- c# sql where in 参数化传值
- 为什么要将图片转为base64格式
- 大数据架构Spark 进阶
- 备份恢复Lesson 07. lmproving Your Backups
- 智原领先推出网通ASIC专用28纳米28G可编程SerDes
- 萤石把直播嵌在html中,直播组件流程使用说明
- 八种常见回归算法解析及代码
热门文章
- oracle hibernate 主键,oracle hibernate 主键自增
- html按键变色,按键变色.html
- 保存到本地_不用任何软件工具找回已保存在本地的网页密码
- python plotly spyder显示_Python绘图工具Plotly的简单使用
- mysql mha配置idrac远程关机_iDRAC远程管理功能试用_戴尔 PowerEdge R810(Xeon E7520/16GB/3*146GB)_服务器评测与技术-中关村在线...
- Notepad++ 配置 Markdown
- Python编程基础11:字典
- Java讲课笔记28:Path接口和Files工具类
- 【HDU5156】Harry and Christmas tree,两种离线的做法
- java线程工作内存在栈中吗_JVM常见面试题解析