通过微调器(C#)

时间:2017-04-27 20:25:03

标签: c# android listview xamarin

我遇到了一个我无法解决的问题,我创建了一个自定义对话框,显示了一个由自定义BaseAdapter填充我的对象的Listview,当我点击EditText时打开这个对话框,所以我可以查看itens我想要的,所有这些都将传递回EditText,见下图:

enter image description here

单击“确定”按钮时,我的EditText将被填充(项目A,项目B) 如果我再次点击EditText,则应检查项目A和项目B ... 我设法做到了这一点,但现在,我需要使用当前类别过滤Listview,为此,我在我的微调器上添加了一个ItemSelect侦听器,它将查询数据库以获取过滤后的itens,清除当前列表,添加了新的列表并在适配器上调用NotifyDataSetChanged(),这很好用。

问题是我需要跟踪所选的itens,即使我更改了类别,例如,我在“类别1”中检查了2个,更改为“类别2”并再次检查了2个,最后,我需要获得所有这4个itens,例如,项目A出现在多个类别中,当我在类别之间进行更改时如何检查它?

目前,这是我的代码:

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;
    }

}

我需要跟踪复选框的位置,所以当我滚动ListView时我可以保持它的状态,否则它会随机检查奇怪的行为......

然后我以这种方式创建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());
        };

我使用ToogleChecked(),所以当我重新打开对话框时,我会保持检查它...

当我单击对话框上的OK按钮时,我只需使用Join函数:

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

要过滤ListView,我这样做:

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

            // Query the database

            animaisAdapter.NotifyDataSetChanged(); }

这种方式非常完美,我想要的方式,但我需要能够过滤这个ListView并始终保持检查itens无数的数据列表中的更改......

任何帮助将不胜感激! 非常感谢你!

1 个答案:

答案 0 :(得分:0)

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