Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android ListView是否使用标记维护状态?_Android_Listview_Checkbox - Fatal编程技术网

Android ListView是否使用标记维护状态?

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()

显然,我的思维有一些缺陷,因为它不能正常工作。基本上,我试图解决这个问题:

在回答中,人们建议创建一个全局数据结构来保存状态,这是有意义的。然而,我认为如果我使用ViewHolder模式,我可以使用标记作为存储状态信息的结构

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……所以如果我重新使用该视图,我需要重新设置侦听器吗?(我假设是这样,但请仔细检查)