【问题标题】:Xamarin custom multiple choice listviewXamarin 自定义多项选择列表视图
【发布时间】:2017-08-13 11:36:52
【问题描述】:

我想知道是否有办法制作一个实际上能够返回所选索引的多选列表视图。我已经能够使用预制的 multiplechoicelistview 适配器来做到这一点,但我需要能够编辑它的样式。所以我需要一个自定义列表视图。 这是我的 oncreate 代码

 protected override void OnCreate(Bundle savedInstanceState)
    {

        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Options);
        outList = FindViewById<ListView>(Resource.Id.outList);
        var btnCheck = FindViewById<ImageButton>(Resource.Id.btnConfirm);
        var btnBack = FindViewById<ImageButton>(Resource.Id.btnBack);
        for (int i = 0; i < NewProfileVars.LifeStyles.Length; i++)
        {
            inList.Add(NewProfileVars.LifeStyles[i].Name);
        }


        //list contents end here

        ListViewAdapter adapter = new ListViewAdapter(this, inList);
        outList.Adapter = adapter;
        outList.ChoiceMode = ChoiceMode.Multiple;
        NewProfile main = new NewProfile();
        btnCheck.Click += Confirm;
        btnBack.Click += Back;


    }

这是我的列表视图适配器代码

    class ListViewAdapter: BaseAdapter<string>
    {
        public List<string> Items;
        public Context Context;

        public ListViewAdapter(Context context, List<string> items)
        {
            Items = items;
            Context = context;
        }


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

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

        }
        public override string this[int position]
        {
            get { return Items[position]; }
        }

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

            if (row == null)
            {
                row = LayoutInflater.From(Context).Inflate(Resource.Layout.ListBox, null, false);

            }
            CheckBox txtName = row.FindViewById<CheckBox>(Resource.Id.cbName);
            txtName.Text = Items[position];
            return row;
        }
    }

我现在只需要弄清楚确认按钮将如何保存我选择的内容。 提前感谢您的帮助。

【问题讨论】:

    标签: c# android listview xamarin xamarin.android


    【解决方案1】:

    我看到您在 ListView 中使用了CheckBox。您可以使用以下方式获取 Checked 所在的项目:

    首先创建一个类来保存您的项目数据和 Checked 状态,例如让我们称之为它

    public class LifeStylesListItem
    {
        public string Name { get; set; }
    
        public bool IsSelected { get; set; }
    
        public LifeStylesListItem(string name)
        {
            Name = name;
        }
    }
    

    然后修改你的ListViewAdapter

    添加一个包含 LifeStylesListItem 列表的新私有字段

    private List<LifeStylesListItem> _list;
    

    使用构造函数中传递的项目初始化列表。

    public ListViewAdapter(Context context, List<string> items)
    {
        Items = items;
        _list = new List<LifeStylesListItem>();
    
        //Your are creating a copy of your Items
        foreach (var item in items)
        {
            _list.Add(new LifeStylesListItem(item));
        }
    
        Context = context;
    }
    

    GetView 方法中订阅 CheckBox 的 CheckedChange 事件。这样,当检查状态发生更改时,您将收到通知。您还需要根据 Item IsSelected 值设置 Checked 属性。当 ListView 将重用您的单元格时,这是必要的。

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
    
        if (row == null)
        {
            row = LayoutInflater.From(Context).Inflate(Resource.Layout.ListBox, null, false);
    
        }
        CheckBox txtName = row.FindViewById<CheckBox>(Resource.Id.cbName);
        txtName.Text = _list[position].Name;
        txtName.Checked = _list[position].IsSelected;
    
        txtName.CheckedChange -= TxtName_CheckedChange;
        txtName.CheckedChange += TxtName_CheckedChange;
    
        return row;
    }
    

    添加事件处理程序TxtName_CheckedChange方法

    void TxtName_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
    {
        //These lines are used to get the position of the control that was clicked
        var obj = sender as CheckBox;
        var row = obj?.Parent as View; 
        var parent = row?.Parent as ListView;
    
        if (parent == null)
        {
            return;
        }
    
        var position = parent.GetPositionForView(row);
    
        // Once you have the position you can get the item and change
        // its IsSelected
        var item = _list[position];
        item.IsSelected = e.IsChecked;
    }
    

    然后添加到适配器中的最后一个方法是返回所选项目的方法。借助Linq(需要添加using System.Linq)可以像这样查询选中的项目。

    public List<string> GetCheckedItems()
    {
        return _list
                .Where(a => a.IsSelected)
                .Select(b => b.Name)
                .ToList();
    }
    

    现在,在您的 Activity 中,您只需在单击 Confirm 按钮时从 ListViewAdapter 方法中调用 GetCheckedItems

    private void Confirm(object sender, EventArgs e)
    {
        var checkedItems = adapter.GetCheckedItems();
    }
    

    记得将 adapter 更改为 Activity 中的私有字段

    private ListViewAdapter adapter;
    

    希望这会有所帮助。-

    【讨论】:

    • 老兄,你是个巫师,非常感谢你,这已经困扰了我好多年了。列表项已经属于一个带有布尔值的结构,所以我只是让 listview 适配器使用该结构。但再次非常感谢你。
    • 等一下,您知道单选单选按钮是如何工作的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多