我想创建一个自定义列表,其中将有复选框,允许您从列表中选择多个项目。与复选框问题的自定义列表视图
带有复选框的列表显示正常,但是如果我选中了一个复选框,然后再滚动列表中的其他项目也会被选中。
它基本上是相同的问题,因为here
我明白,这事做与Android的方式回收的观点,但我不能看到如何解决这个问题!有人可以帮我吗?
谢谢 - Mike
我想创建一个自定义列表,其中将有复选框,允许您从列表中选择多个项目。与复选框问题的自定义列表视图
带有复选框的列表显示正常,但是如果我选中了一个复选框,然后再滚动列表中的其他项目也会被选中。
它基本上是相同的问题,因为here
我明白,这事做与Android的方式回收的观点,但我不能看到如何解决这个问题!有人可以帮我吗?
谢谢 - Mike
您需要一个数据结构来跟踪哪些行被检查。这可以像bool[] checked
那样简单。
在您的getView
中,请确保您将复选框状态设置为checked[position]
的内容。您也应该在getView
的复选框中输入set an OnCheckedChangedListener,以便他们使用更新您的数据。
是的,ListView
中的行会被回收,所以在离开getView
之前,请确保为一行填充所有适当的数据。
创建一个ArrayList<Integer>
。将OnCheckChangedListener
添加到您的复选框。在更改的方法中,将列表视图position
添加到ArrayList<Integer>
或将其删除。
在您的getView
方法中,检查ArrayList<Integer>
是否包含当前列表视图position
。如果它包含该位置,则将选中项设置为true,否则为false。
每当您单击一个复选框时,请从ArrayList
中添加或删除Integer
。
您可以尝试实现OnClickListener复选框而不是OnCheckChangedListener。它为我工作。
检查下面的代码 -
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
ViewHolder holder = new ViewHolder();
if(view == null){
view = inflater.inflate(R.layout.list_callcycle_blue, null);
holder.llContainer = (LinearLayout) view.findViewById(R.id.ll_container);
holder.lblLabel = (TextView) view.findViewById(R.id.txt_desc);
holder.cb = (CheckBox) view.findViewById(R.id.cb_store);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
final Object data = getItem(position);
holder.lblLabel.setText(data.getDescription());
holder.cb.setTag(position);
holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int position = (Integer) buttonView.getTag();
objects.get(position).setChecked(buttonView.isChecked());
}
});
holder.cb.setChecked(isChecked(position));
return view;
}
始终牢记,利用变化holder.cb.setOnCheckedChangeListener()
即任意监听它的设置数据之前,在我们的情况下,它是holder.cb.setChecked()
原因:当我们滚动,listview将回收视图,所以如果在侦听器之前使用了setchecked,那么它将根据旧的侦听器来选择值。如果我们监听后设置它,然后它会采取最新值
编辑的零件 下面部分将展示用于检索isChecked()
和setChecked()
方法是如何检查的数据
/*
* This function is in your Custom Adapter Class
*/
private boolean isChecked(int position){
return object(position).isChecked();
}
/**
* Getter Setter Class/Data Model Class that defines your object
*/
private class MyObject{
private boolean isChecked;
private String a, b, c, orWhateverYourObjectNeeds;
public void setChecked(boolean isChecked){
this.isChecked = isChecked;
}
public boolean isChecked(){
return isChecked
}
}
嗨吉特帕特尔,你能解释你如何从“对象”和“isChecked(位置)”从你的代码在上面?谢谢 – 2015-02-27 15:12:49
已经编辑好久了。忘了沟通,对不起 – 2015-04-12 09:08:37
优秀的作品就像一个魅力!我不知道每次滚动时都会调用getView方法!我认为整个列表被初始化,然后getView方法再也不会被调用了! – mixkat 2011-03-25 22:06:34
我以为我解决了这个问题,但我错了。它很奇怪,因为在setOnCheckedChangeListener中,我必须以相反的方式工作,即如果isChecked,则将数组的相应字段设置为false,否则设置为true。但是当我必须检查哪些盒子被检查时,所有东西都被搞乱了。注意:如果我正确设置它,即当盒子被选中时将数组字段设置为真,那么如果我向下滚动并且再次备份,则丢失所有东西。任何想法为什么发生这种情况? – mixkat 2011-03-26 18:06:42
您确定即使对于循环视图调用'setChecked'?换句话说,if(convertView == null){/ *充满视图* /}/*填充视图,无论在if语句之外再循环/不可循环* /' – 2011-03-26 22:42:23