精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-06-22
最后修改:2010-06-22
CheckBox在ListView 而导致其OnItemClickListener不会被触发
这个标题实在有点长 没办法而为之 本人语言实在乏善可陈 故开题之前 重新描述之
写道
ListView 中的各个item 通过 extends BaseAdapter 可以显示任意子View 当然也包括CheckBox
但是 当使用CheckBox 会导致ListView.setOnItemClickListener(OnItemClickListener listener) 中的listener不会被回调
通过Google 得到以下解释:
写道
ListView的item中加入CheckBox后 导致ListView对OnItemClick事件无法响应 原因是因为CheckBox的事件响应优先级高于List Item,所以屏蔽了ListItem的单击事件
而解决办法是:
写道
设置CheckBox的android:focusable="false"即可
但是 我设置以后 依然无效 只能再想别的办法 以下即为步骤:
[代码 步骤]
1. 鉴于今天重点以ListView 响应OnItemClickListener 故打算其显示item 数据以联系人数据为例
- 查询目标Uri
cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
- 定义PeopleAdapter 用于接收数据源Cursor
public class PeopleAdapter extends BaseAdapter { Activity activity; public PeopleAdapter(Activity a){ activity = a; } @Override public int getCount() { // TODO Auto-generated method stub return cursor.getCount(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub return CheckTest(arg0); } public View CheckTest(int position){ cursor.moveToPosition(position); String name = cursor.getString(cursor.getColumnIndex("name")); CheckBox cb = new CheckBox(activity); cb.setText(name); cb.setFocusable(false); return cb; } }
2. emulator 运行截图
3. 通过ListView.setOnItemClickListener(...) 监听 onItemClick() 但是会失效
lv.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub Log.d("TAG","onItemClick id:"+arg2); } });
4. 下面就涉及 如何解决
写道
正式开始之前 说说其实现原理:
CheckBox 与 ListView.onItemClick() 冲突原因 前面说过 因为优先级问题 那么如果二者所占用的区域不同呢? 即: CheckBox 的区域 就是 CheckBox 本身 而ListView.onItemClick() 监听 可以通过如下: 把CheckBox 放入LinearLayout , 如果单击区域是属于CheckBox 那显然就会执行CheckBox默认行为 即置CheckBox true/false , 如果单击区域处于CheckBox 外 但又属于LinearLayout 那么就视该动作 为ListView.onItemClick()
5. 定义2个int变量 作为CheckBox LinearLayout 的 id 索引起点
public final int LAYOUT_INDEX = 0; public final int CHECKBOX_INDEX = 100;
6. 定义ListView 中 item 的布局 并设立CheckBox LinearLayout 的监听器
public View fromLayout(int position){ cursor.moveToPosition(position); String name = cursor.getString(cursor.getColumnIndex("name")); final LinearLayout layout = new LinearLayout(activity); layout.setOrientation(LinearLayout.HORIZONTAL); layout.setId(position+LAYOUT_INDEX); final CheckBox cb = new CheckBox(activity); cb.setText(name); cb.setBackgroundColor(Color.GRAY); cb.setId(CHECKBOX_INDEX+position); cb.setOnCheckedChangeListener(new OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButton arg0, boolean arg1) { // TODO Auto-generated method stub int id = cb.getId() - CHECKBOX_INDEX; boolean status = arg1; popMessage("CheckBox.onCheckedChanged",id); } }); layout.addView(cb); layout.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub id = arg0.getId() - LAYOUT_INDEX; popMessage("Layout.onClick",id); } }); return layout; }
7. 在PeopleAdapter.getView(int arg0, View arg1, ViewGroup arg2) 使用 fromLayout() 其中 popMessage() 用于通知点击区域和id
public void popMessage(String prefix,int id){ String msg = "["+prefix+"].ID:"+id; Toast.makeText(this,msg,Toast.LENGTH_LONG).show(); }
8. emulator 运行截图 // 为了标记CheckBox显示区域 我用setBackgroundColor(Color.GRAY) 设定其颜色 便于观察
- 点击CheckBox
- 点击其他区域(非CheckBox)
鉴于语言所限 防止有人看不懂 故贴出研究代码 大家自己运行 应该就能理解之了 对了 别忘记顶贴哦!!!!!!
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-06-23
我来顶你.
|
|
返回顶楼 | |
发表时间:2010-06-23
不知有没有简单点的方法呢
|
|
返回顶楼 | |
发表时间:2010-06-23
rainsf 写道 不知有没有简单点的方法呢
目前为止 这是我发现的最简单的解决办法了 |
|
返回顶楼 | |
发表时间:2010-06-23
gryphone 写道 rainsf 写道 不知有没有简单点的方法呢
目前为止 这是我发现的最简单的解决办法了 设置CheckBox的android:focusable="false"是可以做到的,可能是你其他的View设置有问题, 我的很多代码都是使用此方法,不管是CursorAdapter还是ListAdapter,均没问题。 |
|
返回顶楼 | |
发表时间:2010-06-24
sinfrancis 写道 gryphone 写道 rainsf 写道 不知有没有简单点的方法呢
目前为止 这是我发现的最简单的解决办法了 设置CheckBox的android:focusable="false"是可以做到的,可能是你其他的View设置有问题, 我的很多代码都是使用此方法,不管是CursorAdapter还是ListAdapter,均没问题。 我也不知道为什么失败 我也设定了啊 public View CheckTest(int position){ 33. cursor.moveToPosition(position); 34. String name = cursor.getString(cursor.getColumnIndex("name")); 35. 36. CheckBox cb = new CheckBox(activity); 37. cb.setText(name); 38. cb.setFocusable(false); 39. 40. return cb; 41. } |
|
返回顶楼 | |
发表时间:2010-06-29
gryphone 写道 sinfrancis 写道 gryphone 写道 rainsf 写道 不知有没有简单点的方法呢
目前为止 这是我发现的最简单的解决办法了 设置CheckBox的android:focusable="false"是可以做到的,可能是你其他的View设置有问题, 我的很多代码都是使用此方法,不管是CursorAdapter还是ListAdapter,均没问题。 我也不知道为什么失败 我也设定了啊 public View CheckTest(int position){ 33. cursor.moveToPosition(position); 34. String name = cursor.getString(cursor.getColumnIndex("name")); 35. 36. CheckBox cb = new CheckBox(activity); 37. cb.setText(name); 38. cb.setFocusable(false); 39. 40. return cb; 41. } ================================================================== 你这样用,其实一个Item就是一个checkBox,当然设计无效了,你用Layout包含Checkbox的时候,checkbox就好用了。因为这时候checkbox不在占据一行了。 如果你使用xml文件配置这个item布局的话,通常放到某一个Layout里面,在xml文件设计android:focusable="false"是可以的。其实原理是一样的。(只是你理解有点问题,就是checkBox直接显示,就当作一行都是checkbox区域). |
|
返回顶楼 | |
发表时间:2010-06-29
一般这种列表中带checkbox的,我都载对象中定义一个字段。
boolean checked onItemClick(int postiion){ if(data.get(position).checked){ data.get(position).checked= false; }else{ data.get(position).checked = true; } adapter.notifyDateChange(); } |
|
返回顶楼 | |
发表时间:2010-09-08
我只看了标题
没看内容 内容太长了 最简单的办法直接把checkbox的focusable 设为false就OK了 哪那么多废话 |
|
返回顶楼 | |
发表时间:2010-09-08
我也是用的楼主这种方法,问题已经解决了~~
|
|
返回顶楼 | |