Android 在Listview上选择了错误的项目
面对一个非常奇怪的问题。我在每个项目上都有一个带有Android 在Listview上选择了错误的项目,android,listview,simplecursoradapter,onitemclick,Android,Listview,Simplecursoradapter,Onitemclick,面对一个非常奇怪的问题。我在每个项目上都有一个带有复选框的listview,当我点击listview的第一个项目时,它被选中,但与此项目一起,listview的最后一个项目也被选中当我滚动列表视图时。没有卷轴,它工作得很完美 另外,当我选择最后一个项目时,第一个项目将在滚动后与它一起被选择。请注意,第一个和最后一个之间的所有其他项目都正常工作。有趣的是,在选择了第一个或最后一个项目后,如果我不滚动列表视图2-3秒,那么它就工作得很好了。。所以我认为这可能是视图渲染的问题,或者有些问题。谁能告诉我
复选框的listview
,当我点击listview的第一个项目时,它被选中,但与此项目一起,listview的最后一个项目也被选中当我滚动列表视图时。没有卷轴,它工作得很完美
另外,当我选择最后一个项目时,第一个项目将在滚动后与它一起被选择。请注意,第一个和最后一个之间的所有其他项目都正常工作。有趣的是,在选择了第一个或最后一个项目后,如果我不滚动列表视图
2-3秒,那么它就工作得很好了。。所以我认为这可能是视图渲染的问题,或者有些问题。谁能告诉我这到底是怎么回事
Cursor cursor = queryDatabase();
// The desired columns to be bound
String[] columns = new String[] {
DataBaseHelper.ROW_PROFILE_NAME,
DataBaseHelper.ROW_PROFILE_TYPE,
DataBaseHelper.ROW_ID
};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.profileName,
R.id.profileStatus
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
mAdapter = new SimpleCursorAdapter(
this, R.layout.profile_listview_delete_item,
cursor,
columns,
to,
0);
listView = (ListView) findViewById(R.id.profile_listview_delete_main);
// Assign adapter to ListView
listView.setAdapter(mAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
// TODO Auto-generated method stub
CheckBox cb;
Cursor c = mAdapter.getCursor();
String prodile_id = c.getString(c.getColumnIndex(DataBaseHelper.ROW_ID));
cb = (CheckBox)arg1.findViewById(R.id.checkbox);
cb.toggle();
if(cb.isChecked())
{
profileStack.add(prodile_id);
//Toast.makeText(getApplicationContext(), String.valueOf(profileStack), Toast.LENGTH_LONG).show();
counter++;
}
else if(!cb.isChecked())
{
profileStack.remove(prodile_id);
//Toast.makeText(getApplicationContext(), String.valueOf(profileStack), Toast.LENGTH_LONG).show();
counter--;
}
countSelectedItem.setText(String.valueOf(counter)+" items selected");
mAdapter.notifyDataSetChanged();
}
});
Cursor Cursor=queryDatabase();
//要绑定的所需列
字符串[]列=新字符串[]{
DataBaseHelper.ROW\u PROFILE\u名称,
DataBaseHelper.ROW\u PROFILE\u类型,
DataBaseHelper.ROW\u ID
};
//数据将绑定到的XML定义的视图
int[]到=新的int[]{
R.id.profileName,
R.id.profileStatus
};
//使用指向所需数据的光标创建适配器
//以及布局信息
mAdapter=新的SimpleCursorAdapter(
此,R.layout.profile\u列表视图\u删除\u项,
光标,
柱,
到
0);
listView=(listView)findViewById(R.id.profile\u listView\u delete\u main);
//将适配器分配给ListView
setAdapter(mAdapter);
setOnItemClickListener(新的OnItemClickListener(){
@凌驾
public void onItemClick(适配器视图arg0、视图arg1、内部位置、长arg3){
//TODO自动生成的方法存根
复选框cb;
游标c=mAdapter.getCursor();
String profile_id=c.getString(c.getColumnIndex(DataBaseHelper.ROW_id));
cb=(复选框)arg1.findViewById(R.id.CheckBox);
cb.toggle();
if(cb.isChecked())
{
profileStack.add(profile_id);
//Toast.makeText(getApplicationContext(),String.valueOf(profileStack),Toast.LENGTH_LONG.show();
计数器++;
}
如果(!cb.isChecked())
{
profileStack.remove(profile_id);
//Toast.makeText(getApplicationContext(),String.valueOf(profileStack),Toast.LENGTH_LONG.show();
计数器--;
}
countSelectedItem.setText(String.valueOf(counter)+“所选项目”);
mAdapter.notifyDataSetChanged();
}
});
您应该使用一个自定义的适配器
(以及一个模型类,它是可选的
。这里TemaRescatado
是snippet中的一个模型类)。在getView(…)
中,您必须使用try-to-use
代码片段
viewHolder.checkbox = (CheckBox) view.findViewById(R.id.checkBox1);
viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
TemaRescatado element = (TemaRescatado) viewHolder.checkbox
.getTag();
element.setSelected(buttonView.isChecked());
}
});
您应该从AdapterView获取光标,它作为参数传递给onItemClick方法
更改代码
Cursor c = mAdapter.getCursor();
到
发生此问题的原因是ListView
的回收。当第一个可见的视图不可见时,它将重新使用该视图,以显示适配器的下一个数据。因此,当您选中并选中列表
位置中的数据时。它将保持与您离开时相同的状态。因此,我对这个问题的解决方案是:
在适配器的getView()中
放置一个简单的if-else语句,检查是否应选中复选框,如下所示:
// note that this is a pseudo code
if(ID exist in profileStack){
//set checkBox
}
else{
//set checkBox
}
你能发布你的适配器类吗?我想这是视图持有者模式的问题吗?@Rajesh,我使用的是SimpleCrsorAdapter,因为你可以看到上面的代码。你的代码方式是错误的。您必须使用自定义适配器和viewholder类,从该适配器更改复选框的值时,您必须从适配器更改此复选框的字段值。单击listview后,从适配器获取位置和值。检查:。可能重复的。是否可以更正当前代码的问题?因为我告诉过所有其他项目都工作得很好。我不确定,但是,定制适配器不可能更好,因为它将优化您的代码并实现ViewHolder
patternListView的
滚动将平滑。您可以在notifyDataSetChanged()之后使用mAdapter.notifyDataSetInvalidated()
。正如@kaushik建议的那样……使用viewholder,否则您将得到不想要的result@kaushik,notifyDataSetInvalidated()也不起作用,我知道ViewHolder可能会解决此问题,但更改最终应用程序的代码将是一项漫长的任务!不,它不会改变情况。更新了我的答案。检查这个,让我知道它正在工作或不工作。不,它不工作。还是一样,选中第一项,然后滚动浏览,看到最后一项也被选中了!但检查第一项,等待2秒钟,滚动浏览,然后看到它工作良好!奇怪的
// note that this is a pseudo code
if(ID exist in profileStack){
//set checkBox
}
else{
//set checkBox
}