Android 点击 listItem 检查错误的复选框
我通过扩展 SimpleCursorAdapter 创建了一个自定义 ListView。 结果是 IMAGE + CheckedTextView(文本 + 复选框)。
当我长按一个项目时,一切正常 - 我获得了所单击项目的正确 ID 和详细信息。
当我尝试将某个项目标记为已选中但它选中了错误的复选框时,就会出现问题。
例如:我的列表中有 9 项,按 1-9 排序。如果我单击 listItem 1,则会选中第 9 行的复选框。如果我单击第 4 项,则第 6 行上的复选框将被选中,如果我单击中间行,它将被选中。
显然我在这里遗漏了一些东西:) 请记住,当我长按该行(上下文菜单打开)时,一切都很好。
这是听众:
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle);
if (!markedItem.isChecked()) {
markedItem.setChecked(true);
} else {
markedItem.setChecked(false);
}
}
});
感谢任何帮助!
如果您需要我发布更多代码,请告诉我。
谢谢你!
顺便说一句,如果我点击多个...派对继续...没有明显的顺序...
编辑:适配器代码
public class ImageCursorAdapter extends SimpleCursorAdapter {
private Cursor c;
private Context context;
private String url;
private TextView bUrl;
public ImageCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.image_list, null);
}
this.c.moveToPosition(pos);
final TextView bTitle = (TextView) v.findViewById(R.id.btitle);
String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE));
byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON));
if (favicon != null) {
ImageView iv = (ImageView) v.findViewById(R.id.bimage);
iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length));
}
bTitle.setText(bookmark);
return (v);
}
}
I've created a custom ListView by extending SimpleCursorAdapter.
The result is IMAGE + CheckedTextView (Text + Checkbox).
When I long click an Item, everything works fine - I get the right ID and details of the clicked Item.
The problem occurs when I try to mark an Item as checked but it checks the wrong checkbox.
For example: I have 9 items on my list, sorted 1-9. if I click on listItem 1, the checkbox on line 9 is being checked. if I click on item 4, the checkbox on line 6 is being checked and if I click on the middle line, it is being checked.
Clearly I'm missing something here :)
Do remember when I long click the line (contextMenu opens), everything works great.
This is the listener:
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle);
if (!markedItem.isChecked()) {
markedItem.setChecked(true);
} else {
markedItem.setChecked(false);
}
}
});
Appreciate any help!
Let me know If you need me to post more code.
Thank you!
btw, If I click on more than one... the PARTY continues... no obvious order...
EDIT: the Adapter code
public class ImageCursorAdapter extends SimpleCursorAdapter {
private Cursor c;
private Context context;
private String url;
private TextView bUrl;
public ImageCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.image_list, null);
}
this.c.moveToPosition(pos);
final TextView bTitle = (TextView) v.findViewById(R.id.btitle);
String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE));
byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON));
if (favicon != null) {
ImageView iv = (ImageView) v.findViewById(R.id.bimage);
iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length));
}
bTitle.setText(bookmark);
return (v);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Mayra 是对的 - 问题与 ListView 重用视图的方式有关。并不是说有 9 个
CheckedTextView
对象实例,每个视图一个。相反,只有一个在所有行中都重复使用。因此,您不能依赖 CheckedTextView 对象来保存项目是否被选中的状态。您将需要一些额外的数据结构来保存是否检查给定的行,例如,如果应检查第 i 个行,则第 i 个元素为 true。然后在您的 itemClickListener 中:
然后在您的视图代码中:
这应该可以解决您的问题。另一种方法是将行是否被检查的逻辑移动到该行所代表的域对象中。那是我的偏好。
Mayra is right - the problem has to do with the way the ListView is reusing your views. It's not as if there are 9 instances of the
CheckedTextView
object, one per view. Instead, there's a single one that is reused in all the rows. Thus you can't rely on the CheckedTextView object to hold the state of whether an item is checked. You'll need some additional data structure to hold whether a given row is checked For instance,Where the
ith
element is true iff theith
row should be checked. Then within your itemClickListener:Then within your view code:
This should solve your problem. An alternative approach would be to move the logic of whether the row is checked or not into the domain object that the row represents. That would be my preference.