简体   繁体   English

通过微调框(C#)过滤后,在Listview上维护选中的itens

[英]Maintain checked itens on a Listview when filtered by spinner (C#)

I'm running into a problem that I cannot fix, I created an custom dialog that shows a Listview filled with my objects by an custom BaseAdapter, I open this dialog when I click into an EditText, so I can check the itens that I want, and all this itens will be passed back to the EditText, see the image below: 我遇到了无法解决的问题,创建了一个自定义对话框,其中显示了一个由自定义BaseAdapter填充对象的Listview,当我单击EditText时,我打开了此对话框,因此可以检查所需的itens ,所有这些内容将传递回EditText,请参见下图:

在此处输入图片说明

When I click the OK button, my EditText will be filled with (Item A, Item B) And if I click again on the EditText, Item A and Item B should be already checked... I managed to do this, but now, I need to filter the Listview with the current category, to do this, I added an ItemSelect listener on my spinner that will query the database to get the filtered itens, cleared my current list, added the new list and called NotifyDataSetChanged() on the adapter, this works just fine. 当我单击“确定”按钮时,我的EditText将充满(项目A,项目B)。如果再次单击EditText,则应该已经检查项目A和项目B ...我设法做到了,但是现在,我需要使用当前类别过滤Listview,为此,我在微调器上添加了一个ItemSelect侦听器,该侦听器将查询数据库以获取过滤后的itens,清除当前列表,添加新列表,并在适配器,这很好用。

The problem is that I need to keep track of the selected itens even if I change the categories, for instance, I checked 2 itens in the "Category one", changed to "Category two" and checked 2 more itens, at the end, I need to get all these 4 itens, and for example, Item A is present in more then one category, how do I keep it checked when I change between the categories? 问题是,即使我更改类别,我也需要跟踪选定的iten,例如,我在“ Category one”中检查了2个itens,更改为“ Category 2”,并在最后检查了2个iten,我需要获取所有这4个iten,例如,项目A出现在一个以上的类别中,当我在各个类别之间切换时,如何保持选中状态?

For now, this is my codes: 现在,这是我的代码:

class MultipleAnimalSelectionAdapter : BaseAdapter<AnimalBean>
{
    private List<AnimalBean> animaisList;
    private Context cx;
    private Dictionary<int, bool> checkedAnimals = new Dictionary<int, bool>();

    public MultipleAnimalSelectionAdapter(Context cx, List<AnimalBean> animaisList)
    {
        this.cx = cx;
        this.animaisList = animaisList;
        for (int i = 0; i < animaisList.Count; i++)
        {
            checkedAnimals.Add(i, false);
        }
    }

    public override AnimalBean this[int position]
    {
        get
        {
            return animaisList[position];
        }
    }

    public override int Count
    {
        get
        {
            return animaisList.Count;
        }
    }

    public override long GetItemId(int position)
    {
        return position;
    }


    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        ViewHolder viewHolder;

        if (row == null)
        {
            row = LayoutInflater.From(cx).Inflate(Resource.Layout.dialog_animais_row, null, false);
            viewHolder = new ViewHolder();
            viewHolder.CbAnimal = row.FindViewById<CheckBox>(Resource.Id.cbAnimal);

            row.Tag = viewHolder;
        }
        else
        {
            viewHolder = (ViewHolder)row.Tag;
        }

        AnimalBean animal = (AnimalBean) GetItem(position);

        viewHolder.CbAnimal.Clickable = false;
        viewHolder.CbAnimal.Focusable = false;
        viewHolder.CbAnimal.Text = animal.AnimalNome;
        viewHolder.CbAnimal.Tag = position;

        if (checkedAnimals[(int)viewHolder.CbAnimal.Tag])
            viewHolder.CbAnimal.Checked = true;
        else
            viewHolder.CbAnimal.Checked = false;
        return row;
    }

    public void ToogleChecked(int position)
    {
        if (checkedAnimals[position])
            checkedAnimals[position] = false;
        else
            checkedAnimals[position] = true;

        NotifyDataSetChanged();
    }

    public void ToogleChecked(AnimalBean animal)
    {
        for(int i = 0; i < animaisList.Count; i++)
        {
            if (animaisList[i].AnimalId == animal.AnimalId)
                ToogleChecked(i);
        }

        NotifyDataSetChanged();
    }

    public List<int> GetCheckedAnimaisPosition()
    {
        List<int> checkedPos = new List<int>();
        for(int i = 0; i < checkedAnimals.Count; i++)
        {
            if(checkedAnimals[i])
            {
                checkedPos.Add(i);
            }
        }
        return checkedPos;
    }

    public List<AnimalBean> GetCheckedAnimais()
    {
        List<AnimalBean> animais = new List<AnimalBean>();

        for(int i = 0; i < checkedAnimals.Count; i++)
        {
            if (checkedAnimals[i])
                animais.Add(animaisList[i]);
        }

        return animais;
    }

    // ViewHolder class
    private class ViewHolder : Java.Lang.Object
    {
        public CheckBox CbAnimal;
    }

}

I needed to keep track of the checkbox position, so I could maintain it status when I scroll the ListView, otherwise it would act strange checking random itens... 我需要跟踪复选框的位置,以便在滚动ListView时可以保持其状态,否则检查随机itens会产生奇怪的结果...

Then I create the ListView this way: 然后我以这种方式创建ListView:

        ListView lvDialogAnimais = dialog.FindViewById<ListView>(Resource.Id.lvDialogAnimais);
        MultipleAnimalSelectionAdapter animaisAdapter = new MultipleAnimalSelectionAdapter(this, animaisList);
        lvDialogAnimais.Adapter = animaisAdapter;

        foreach (AnimalBean selAnimal in selectedAnimais)
        {
            animaisAdapter.ToogleChecked(selAnimal);
        }

        lvDialogAnimais.ItemClick += (ss, ee) =>
        {
            animaisAdapter.ToogleChecked(ee.Position);
            selectedAnimais.Clear();
            selectedAnimais.AddRange(animaisAdapter.GetCheckedAnimais());
        };

I use the ToogleChecked() so I keep the checked itens when I reopen the dialog... 我使用ToogleChecked(),所以当我重新打开对话框时,我保持选中的itens ...

And when I click the OK button on my dialog, I simple use a Join function: 当我单击对话框上的“确定”按钮时,我简单地使用了Join函数:

Button btnCDOk = dialog.FindViewById<Button>(Resource.Id.btnCDOk);
        btnCDOk.Click += (ss, ee) =>
        {
            tmp.Text = string.Join(", ", selectedAnimais);
            dialog.Dismiss();
        };

To filter the ListView, I do this: 要过滤ListView,请执行以下操作:

spinDialogCategorias.ItemSelected += (ss, ee) =>
        {
            animaisList.Clear();

            // Query the database

            animaisAdapter.NotifyDataSetChanged(); }

This works just perfect, the way I want, but I need to be able to filter this ListView and always maintain the checked itens ragardless of changes in the data list... 这可以按我想要的方式完美地工作,但是我需要能够过滤此ListView并始终保持检查过的itens不受数据列表中的更改的影响。

Any help will be appreciated! 任何帮助将不胜感激! Thank you very much! 非常感谢你!

也许您可以只建立一个临时列表,在其中跟踪这对夫妇,然后可以迭代该列表,以构建一个元素数组以传递给您的适配器(或者您可以将该列表传递给新的适配器),之后调用NotifyDataSetChanged()重绘listView

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM