Android - 由于回收问题而无法检查自定义列表视图中的所有复选框?

发布于 2024-11-01 15:02:18 字数 4068 浏览 1 评论 0原文

我有一个自定义列表视图适配器,带有图像视图、文本视图和复选框。我的主布局中还有一个按钮和一个复选框(不在列表视图中)。

我想要的是当我检查主布局的复选框时立即检查所有这些列表视图复选框。

我将这些复选框的状态保存在布尔类型数组列表中,这样当我逐一检查时,我就可以检查这些复选框,但到目前为止,我没有找到一种方法可以立即检查所有这些复选框,我可以在我的主布局的复选框的 OnCheckedChanged 事件。

我尝试了一些技术,但由于 ListView 的回收过程,它只检查当前可见的那些项目,当我向下滚动到我的列表时,所有上述项目都设置为未选中,并且一些随机项目被检查。

如何克服这个回收问题以及如何一次检查所有这些复选框???有什么建议吗?解决方案?主意?

这是我的自定义适配器的代码: -

public class IconAdapter extends BaseAdapter
{ 
private Activity activity;
private Object[] data;
private ArrayList<HashMap<String,String>> listItems;
public static LayoutInflater inflater = null;
private PackageManager pm;
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
private ArrayList<String> itemSelected = new ArrayList<String>();
private ArrayList<CheckBox> ctv = new ArrayList<CheckBox>();

public IconAdapter(Activity a, ArrayList<HashMap<String,String>> items)
{
    activity = a;
    listItems = items;
    data = items.toArray();
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    pm = a.getPackageManager();
    for(int i = 0; i < items.size(); i++)
    {
        itemChecked.add(i,false);
    }
    for(int i = 0; i < items.size(); i++)
    {
        itemSelected.add(i," ");
    }

}

public int getCount() {
    return listItems.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public static class ViewHolder{
    public TextView textView;
    public ImageView imageView;
    public CheckBox checkBox;
}

public View getView(final int position, View convertView, ViewGroup parent)
{
    View row = convertView;
    ViewHolder holder;
    if(convertView==null)
    {
        row = inflater.inflate(R.layout.item, parent, false);
        holder = new ViewHolder();
        holder.textView = (TextView)row.findViewById(R.id.text1);
        holder.checkBox = (CheckBox)row.findViewById(R.id.check);
        holder.imageView = (ImageView)row.findViewById(R.id.image);
        holder.checkBox.setTag(position);
        row.setTag(holder);
    }
    else
    {
        holder = (ViewHolder)row.getTag();
    }


    String s = data[position].toString();
    String[] tokens = s.split(",");
    String[] mToken = tokens[0].split("=");
    String taskName = mToken[1];
    String[] mTokens = tokens[1].split("=");
    final String pkgName =  mTokens[1].substring(0, (mTokens[1].length() - 1));


    holder.textView.setText(taskName);



    ctv.add(holder.checkBox);
    holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton button, boolean b) {
            //int posClicked = ((Integer)button.getTag());
            if(b)
            {
                itemChecked.set(position, true);
                itemSelected.set(position, pkgName);

            }
            else
            {
                itemChecked.set(position,false);

            }
        }
    });





    holder.checkBox.setChecked(itemChecked.get(position));




    try{
        Drawable icon =   pm.getApplicationIcon(pkgName);
        holder.imageView.setImageDrawable(icon);
    }
    catch (PackageManager.NameNotFoundException ne)
    {

    }
     row.setId(position);
     return row;
}

public boolean isChecked(int position)
{
    return itemChecked.get(position);
}
public String getPkgName(int position)
{
    return itemSelected.get(position);
}
public void removeItem(int position)
{
    listItems.remove(position);
}




public void setItemChecked(boolean isChecked)
{
    if(isChecked)
    {
        for(int i = 0; i < ctv.size(); i++)
        {

            ctv.get(i).setChecked(true);
        }
    }
    else
    {
        for(int i = 0; i < ctv.size(); i++)
        {

            ctv.get(i).setChecked(false);
        }
    }
}

正如您在该适配器的末尾所看到的,我创建了一个函数 setItemChecked() 但该函数也是回收过程的受害者,因为它只检查可见项目并且当我向下滚动它时开始行为不端。

任何帮助都会很棒。

谢谢。

I have a custom listview adapter with a imageview, textview and a checkbox. and i also have a button and a checkbox in my main layout(not in listview).

What here i want is to check all these listview checkboxes at once when i check my main layout's checkbox.

And i am saving the state of these checkbox in boolean type arraylist so i am able to check these checkboxes when i check one by one but so far i did not find a single way to check all these checkbox at once which i can use in my main layout's checkbox's OnCheckedChanged event.

i tried few techniques but because of ListView's recycling procedure it checks only those items which are currently visible and as i scroll down to my list, all the above items set to unchecked and some random items got checked.

how to get over this recycle thing and how to check all these checkboxes at once???? any advise? solution? idea?

here is a code of my Custom Adapter : -

public class IconAdapter extends BaseAdapter
{ 
private Activity activity;
private Object[] data;
private ArrayList<HashMap<String,String>> listItems;
public static LayoutInflater inflater = null;
private PackageManager pm;
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
private ArrayList<String> itemSelected = new ArrayList<String>();
private ArrayList<CheckBox> ctv = new ArrayList<CheckBox>();

public IconAdapter(Activity a, ArrayList<HashMap<String,String>> items)
{
    activity = a;
    listItems = items;
    data = items.toArray();
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    pm = a.getPackageManager();
    for(int i = 0; i < items.size(); i++)
    {
        itemChecked.add(i,false);
    }
    for(int i = 0; i < items.size(); i++)
    {
        itemSelected.add(i," ");
    }

}

public int getCount() {
    return listItems.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public static class ViewHolder{
    public TextView textView;
    public ImageView imageView;
    public CheckBox checkBox;
}

public View getView(final int position, View convertView, ViewGroup parent)
{
    View row = convertView;
    ViewHolder holder;
    if(convertView==null)
    {
        row = inflater.inflate(R.layout.item, parent, false);
        holder = new ViewHolder();
        holder.textView = (TextView)row.findViewById(R.id.text1);
        holder.checkBox = (CheckBox)row.findViewById(R.id.check);
        holder.imageView = (ImageView)row.findViewById(R.id.image);
        holder.checkBox.setTag(position);
        row.setTag(holder);
    }
    else
    {
        holder = (ViewHolder)row.getTag();
    }


    String s = data[position].toString();
    String[] tokens = s.split(",");
    String[] mToken = tokens[0].split("=");
    String taskName = mToken[1];
    String[] mTokens = tokens[1].split("=");
    final String pkgName =  mTokens[1].substring(0, (mTokens[1].length() - 1));


    holder.textView.setText(taskName);



    ctv.add(holder.checkBox);
    holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton button, boolean b) {
            //int posClicked = ((Integer)button.getTag());
            if(b)
            {
                itemChecked.set(position, true);
                itemSelected.set(position, pkgName);

            }
            else
            {
                itemChecked.set(position,false);

            }
        }
    });





    holder.checkBox.setChecked(itemChecked.get(position));




    try{
        Drawable icon =   pm.getApplicationIcon(pkgName);
        holder.imageView.setImageDrawable(icon);
    }
    catch (PackageManager.NameNotFoundException ne)
    {

    }
     row.setId(position);
     return row;
}

public boolean isChecked(int position)
{
    return itemChecked.get(position);
}
public String getPkgName(int position)
{
    return itemSelected.get(position);
}
public void removeItem(int position)
{
    listItems.remove(position);
}




public void setItemChecked(boolean isChecked)
{
    if(isChecked)
    {
        for(int i = 0; i < ctv.size(); i++)
        {

            ctv.get(i).setChecked(true);
        }
    }
    else
    {
        for(int i = 0; i < ctv.size(); i++)
        {

            ctv.get(i).setChecked(false);
        }
    }
}

as you can see in the end of this adapter i made a function setItemChecked() but this function is also a victim of recycle process as its only checking the visible item and as i scroll down it starts misbehaving.

any help would be great.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

硪扪都還晓 2024-11-08 15:02:18

今天早上我读到了这样一个问题的答案,他们建议我们将 holder.checkBox.setChecked(itemChecked.get(position)); 放在 holder.checkBox.setOnCheckedChangeListener 之前>

所以,getView函数将被重写为这样:

public View getView(....)
{
    ...
    holder.checkBox.setChecked(itemChecked.get(position));///move to here
    holder.checkBox.setOnCheckedChangeListener(...);
    ...
)

This morning I read an answer of an issue like this, and they recommend we put holder.checkBox.setChecked(itemChecked.get(position)); before holder.checkBox.setOnCheckedChangeListener

So, getView function will be rewritten like this:

public View getView(....)
{
    ...
    holder.checkBox.setChecked(itemChecked.get(position));///move to here
    holder.checkBox.setOnCheckedChangeListener(...);
    ...
)
陌伤浅笑 2024-11-08 15:02:18

是的,这种回收很痛苦。

这就是我所做的:
http://dev.kafol.net/2011 /11/android-checkbox-listview-un-check-all.html

我仍然遇到 SharedPreferences 的一些问题,因为尽管我已经设法选中或取消选中所有复选框,但它仍然无法保存共享偏好的状态。

Yeah, this recycling is a pain.

Here's what I did:
http://dev.kafol.net/2011/11/android-checkbox-listview-un-check-all.html

I'm still having some issues with SharedPreferences, as allthough I have managed to get all the checkboxes checked or unchecked, it still doesn't save the state to sharedpreferences.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文