Android ListView是否使用标记维护状态?
显然,我的思维有一些缺陷,因为它不能正常工作。基本上,我试图解决这个问题: 在回答中,人们建议创建一个全局数据结构来保存状态,这是有意义的。然而,我认为如果我使用ViewHolder模式,我可以使用标记作为存储状态信息的结构Android ListView是否使用标记维护状态?,android,listview,checkbox,Android,Listview,Checkbox,显然,我的思维有一些缺陷,因为它不能正常工作。基本上,我试图解决这个问题: 在回答中,人们建议创建一个全局数据结构来保存状态,这是有意义的。然而,我认为如果我使用ViewHolder模式,我可以使用标记作为存储状态信息的结构 cbox.setOnClickListener(new OnClickListener() { public void onClick(View v) { P tag = (P) ((View) v.getParent()).getTag()
cbox.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
P tag = (P) ((View) v.getParent()).getTag();
if(tag.cbox.isChecked())
tag.cbox.setChecked(true);
else
tag.cbox.setChecked(false);
//tag.cbox.toggle();
Log.d("YoYo", Boolean.toString(tag.cbox.isChecked()));
}
});
上面的代码没有在行中切换我的复选框。我做错了什么
更新:而不是切换,如果语句似乎有效,则手动。不过,我遇到了另一个问题,当我滚动到不同的地方后,检查状态就乱了。为什么呢?如果我在tag.cbox中设置了checked状态,那么check状态是否仅对该对象唯一
更新2:我按照别人的建议得到了一个可用的版本,但我仍然想知道为什么setTag/getTag不可用? 工作:
public View getView(final int position, View view, ViewGroup parent)
{
Plurker tag = getItem(position);
if (view == null)
view = adapterLayoutInflater.inflate(R.layout.adapter, null);
tag.avatar = (ImageView) view.findViewById(R.id.imgAvatar);
tag.cbox = (CheckBox) view.findViewById(R.id.cBox);
tag.cbox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton btn, boolean isChecked)
{
int pos = position;
Plurker p = getItem(pos);
p.isChecked = isChecked;
Log.d("PLURK", "Listener:" + p.toString());
}
});
tag.update(getItem(position));
Log.d("PLURK", tag.cbox.getText() + ":" + Integer.toString(position));
return view;
}
不工作:
public View getView(final int position, View view, ViewGroup parent)
{
Plurker tag = getItem(position);
if (view == null)
{
view = adapterLayoutInflater.inflate(R.layout.adapter, null);
tag.avatar = (ImageView) view.findViewById(R.id.imgAvatar);
tag.cbox = (CheckBox) view.findViewById(R.id.cBox);
tag.cbox.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0)
{
int pos = position;
Plurker p = getItem(pos);
p.isChecked = !p.isChecked;
Log.d("PLURK", "Listener:" + p.toString());
}
});
view.setTag(tag);
}
else
tag = (Plurker) view.getTag();
tag.update(getItem(position));
Log.d("PLURK", tag.cbox.getText() + ":" + Integer.toString(position));
return view;
}
在“不工作”版本中,我需要使用onClick而不是onCheckedChanged事件,因为当视图从隐藏状态重新出现时,它调用了事件侦听器,因此它会被错误触发 您是每次对新视图进行充气还是使用传入的convertView 通常,适配器尝试回收视图,只创建足够的视图以提供平滑的滚动。现有的回收视图作为convertView传入。您可以每次充气并返回新视图(昂贵),也可以根据位置重新设置convertView(如果存在)。如果回收,您需要重新设置所有视图属性,因为无法保证您获得的回收视图与以前用于此位置的视图相同
听起来您的错误在于您没有正确地重新设置回收视图(convertView)的所有属性以匹配当前位置的数据。根据链接所述,他们希望您将检查状态存储在字符串数组中,而不是标记中。试试看,希望这对你有用。@maebe谢谢!但我认为这不是问题所在。事实上,我解决了第一个问题,但现在还有另一个问题:S@Patrick你在找什么?@Samir Hi,我在找为什么单击第一行的复选框,向下滚动,第9个和第18个复选框也被选中。@Patrick查看我的答案和它为我所做的工作,它的源代码在下面,它的多项目被选中listview……所以如果我重新使用该视图,我需要重新设置侦听器吗?(我假设是这样,但请仔细检查)