简体   繁体   English

自定义多选列表视图Android

[英]Custom multiselected listview Android

I have been trying create a multiselected ListView like it looks on picture in this link: picture When user unchecked the checkbox in the top-left corner listviewItem layout must be changed to unchecked state. 我一直在尝试创建一个多选ListView,就像它在此链接中的图片一样picture当用户取消选中时,左上角listviewItem布局中的复选框必须更改为未选中状态。 Now I use it: 现在我使用它:

public class ProcedureAdapter : BaseAdapter<Procedure>
{
    List<Procedure> items;
    Activity context;
    Dictionary<int, bool> CheckedItems = new Dictionary<int, bool>();
    public ProcedureAdapter(Activity context, List<Procedure> items)
        : base()
    {
        this.context = context;
        this.items = items;
        for (int i = 0; i < items.Count; i++)
        {
            CheckedItems.Add(i, false);
        }
    }
    public override long GetItemId(int position)
    {
        return position;
    }
    public override Procedure this[int position]
    {
        get { return items[position]; }
    }
    public override int Count
    {
        get { return items.Count; }
    }

    public void toggleCheck(int position)
    {
        if (CheckedItems.ContainsKey(position))
        {
            CheckedItems[position] = !CheckedItems[position];
            base.NotifyDataSetChanged();
        }
    }
    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        var item = items[position];
        View view = convertView;
        if (view == null) 
            view = context.LayoutInflater.Inflate(Resource.Layout.ProcedureListViewItem, null);

        if (!CheckedItems.ContainsKey(position))
            CheckedItems.Add(position, false);

        if (CheckedItems[position])
        {
            checkBox.Visibility = ViewStates.Visible;
            checkBox.Checked = true;
            ProcedureTypeImage.Visibility = ViewStates.Gone;
        }
        else
        {
            checkBox.Visibility = ViewStates.Gone;
            checkBox.Checked = false;
            ProcedureTypeImage.Visibility = ViewStates.Visible;
        }



        return view;
    }
}

In the activity: 在活动中:

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = inflater.Inflate(Resource.Layout.ProceduresLayout, container, false);
        listView = view.FindViewById<ListView>(Resource.Id.listView1);
        listView.ItemLongClick += listView_ItemLongClick;
        procAdapter = new ProcedureAdapter(Activity, procedures);
        listView.Adapter = procAdapter;

        return view;
    }

    void listView_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
    {
        procAdapter.toggleCheck(e.Position);
    }

but i faced with problem: how can I change layout when user unchecked the checkbox? 但是我面临一个问题:当用户取消选中复选框时,如何更改布局? I have tried processing CheckedChange event in the Adapter, but how I will know position of this ListViewItem? 我已经尝试在适配器中处理CheckedChange事件,但是我如何知道此ListViewItem的位置? My solution seems to me not very good, please give me advice how can I do it better. 在我看来,我的解决方案不是很好,请给我建议如何做得更好。 I was wondering if you show to me a simple example on C# or Java. 我想知道您是否向我展示了一个有关C#或Java的简单示例。 Thanks 谢谢

I made a simple example that might help you. 我举了一个简单的例子,可能会对您有所帮助。 It's a list and each list item has a TextView and CheckBox. 这是一个列表,每个列表项都有一个TextView和CheckBox。 Text view is showing position in green or red color depending on if check box checked or not. 文本视图以绿色或红色显示位置,具体取决于是否选中了复选框。 It is simplified version of your problem. 它是您问题的简化版本。 Don't know if it's best solution but it will work. 不知道这是否是最佳解决方案,但它会起作用。

Only thing to note. 唯一要注意的事情。 Since views are being reused when you bind check box it can trigger CheckedChange event. 由于绑定绑定时视图被重用,因此它可以触发CheckedChange事件。 That is why Tag is first changed when doing the binding. 这就是为什么在进行绑定时首先更改Tag的原因。

using System.Globalization;
using Android.App;
using Android.Graphics;
using Android.Views;
using Android.Widget;
using Object = Java.Lang.Object;

namespace AndroidApplication1
{
    public class LvAdapter : BaseAdapter
    {
        private readonly Activity _context;
        public bool[] Bools = new bool[15];

        public LvAdapter(Activity context)
        {
            _context = context;
        }

        public override Object GetItem(int position)
        {
            return null;
        }

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

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            ViewHolder vh;

            var view = convertView;
            if (view == null)
            {
                view = _context.LayoutInflater.Inflate(Resource.Layout.list_item, parent, false);
                vh = new ViewHolder();
                vh.Initialize(view, this);
                view.Tag = vh;
            }
            vh = view.Tag as ViewHolder;
            if (vh != null) vh.Bind(position, Bools);
            return view;
        }

        public override int Count
        {
            get { return Bools.Length; }
        }

        private class ViewHolder : Object
        {
            private TextView _text;
            private CheckBox _check;

            public void Initialize(View view, LvAdapter adapter)
            {
                _text = view.FindViewById<TextView>(Resource.Id.tvText);
                _check = view.FindViewById<CheckBox>(Resource.Id.cbCheck);

                _check.CheckedChange += (sender, args) =>
                {
                    var tagHoldr = (((View) sender).Tag) as TagHolder;
                    adapter.Bools[tagHoldr.Positon] = args.IsChecked;
                    tagHoldr.TextView.SetTextColor(args.IsChecked ? Color.Green : Color.Red);
                };
            }

            public void Bind(int position, bool[] bools)
            {
                _check.Tag = new TagHolder { Positon = position, TextView = _text };
                _text.Text = position.ToString(CultureInfo.InvariantCulture);
                _check.Checked = bools[position];
                _text.SetTextColor(bools[position] ? Color.Green : Color.Red);
            }
        }

        private class TagHolder : Object
        {
            public int Positon { get; set; }
            public TextView TextView { get; set; }
        }
    }
}

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

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