1

我需要用复选框实现列表视图。如果我选中 10 个中的 4 个复选框,则单击一个按钮后,无论选中什么复选框,都必须找到这些行(对象)详细信息。我搜索了很多,但在 monodroid 中找不到解决方案。请帮我。

4

2 回答 2

0

因此,不幸的是,解决您的问题涉及很多细节。我自己也为此苦苦挣扎。没有示例项目,但我试图从工作解决方案中删除不必要的部分。希望这至少有助于概述我创建的结构。

适配器

public class MyItemListAdapter : BaseAdapter
{
    private OrderedDictionary<Guid, ObjectRespresentingSingleRow> _items = new OrderedDictionary<Guid, ObjectRespresentingSingleRow>();
    private GuidHashSet _selectedItems = new GuidHashSet();

    public ICollection<ObjectRespresentingSingleRow> Items
    {
        get { return _itmes.Values; }
    }

    public event EventHandler<IntegerEventArgs> SelectedItemsChanged;
    public event EventHandler<IntegerEventArgs> ItemsNumberChanged;

    public void Add(ObjectRespresentingSingleRow item)
    {
        _items.Add(item.Id, item);
        // Fire the ItemsNumberChanged event here
        NotifyDataSetChanged();
    }

    public void SelectAll()
    {
        _selectedItems.UnionWith(_items.Keys);
        // Fire SelectedEventsChanged here
        NotifyDataSetChanged();
    }

    public void ClearSelected()
    {
        _selectedItems.Clear();
        // Fire SelectedEventsChanged here
        NotifyDataSetChanged();
    }

    // Will need to add all the overrides as well as some methods like (RemoveAllSelected(), SelectAt(), Clear(), ... etc)

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        ItemViewHolder viewHolder;
        ObjectRespresentingSingleRow listItem = _items[position].Value;
        if (convertView == null)
        {
            viewHolder = new ItemViewHolder();
            convertView = _inflater.Inflate(Resource.Layout.LayoutItemListViewRow, null);

            viewHolder.CheckBox = convertView.FindViewById<CheckBox>(Resource.Id.ItemListViewRowCheckBoxSelected);
            viewHolder.OtherView = convertView.FindViewById<TextView>(Resource.Id.ItemListViewRowTextViewName);

            // I also had to use a TouchDelegate on the CheckBox to extend the checkbox touchable area

            // Save the view holder so that we do not have to find these view again for this particular item
            convertView.Tag = viewHolder;
        }
        else
        {
            // Use the previous view holder (performance)
            viewHolder = (ItemViewHolder)convertView.Tag;
        }

        // Since the views are reusable we need to rotate the click handlers for the views
        viewHolder.CheckBox.Click -= viewHolder.ClickHandler;
        viewHolder.ClickHandler = (object sender, EventArgs args) =>
        {
            CheckBox checkBox = (CheckBox)sender;
            if (checkBox.Checked)
            {
                _selectedItems.Add(listItem.Id);
            }
            else
            {
                _selectedItems.Remove(listItem.Id);
            }
            // Fire SelectedItemsChanged event here with the current number of selected items
        };
        viewHolder.CheckBox.Click += viewHolder.ClickHandler;

        // Popolate the view based on the event data
        viewHolder.OtherView.Text = listItem.Text;
        viewHolder.CheckBox.Checked = _selectedItems.Contains(listItem.Id);
        // Populate the rest of the view ... etc

        return convertView;
    }
}

显示列表的 Activity/Fragment

private MyItemListAdapter _itemListAdapter = null;
    private ItemListActionCallback _actionCallback = null;

private void OnCreate()
{
    _itemListAdapter = new MyItemListAdapter(Activity);
        _itemListAdapter.ItemsNumberChanged += OnItemsNumberChanged;
        _itemListAdapter.SelectedItemsChanged += OnSelectedItemsChanged;
        mainListView.ItemClick += OnItemsClicked; // Navigate to the item as well when area away from checkbox is touched
        mainListView.Adapter = _itemListAdapter;
}

private void OnItemsNumberChanged(object sender, IntegerEventArgs args)
    {
        // Display empty if args.Value == 0 or something like it
    }


private void OnSelectedItemsChanged(object sender, IntegerEventArgs args)
    {
        if (args.Value == 0)
        {
            if (_actionMode != null)
            {
                // The last selected event was unselected, therefore exit action mode
                _actionMode.Finish();
            }
        }
        else
        {
            if (_actionMode == null)
            {
                // At least one event was selected, start action mode
                _actionMode = Activity.StartActionMode(_actionCallback);
            }
            // Update the action bar with the total number of selected events
            _actionMode.Title = args.Value; // Format this 
        }
    }

如果您想通过操作栏对选定对象执行某些操作,您也必须执行此操作。

public class ItemListActionCallback : Java.Lang.Object, ActionMode.ICallback
{
    private readonly MyItemListAdapter _adapter = null;

    public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
    {
        switch (item.ItemId)
        {
            case Resource.Id.MenuDelete:
                // Delete from local storage as well as from the adapater
                _adapter.RemoveSelected();
                _adapter.NotifyDataSetChanged();
                mode.Finish();
                break;
            case Resource.Id.MenuSelectAll:
                _adapter.SelectAll();
                break;
            default:
                mode.Finish();
                break;
        }
        return true;
    }

    // See other examples on how to implement the rest
}

还要确保您的 CheckBox 具有以下内容:

android:focusable="false"

这基本上模仿了 Gmail 的功能。

于 2013-09-25T23:19:52.623 回答
0

您应该在 LISTVIEW 中使用这种类型的 ADAPTER WITH CHECK BOX:here getView 方法用于 BaseAdapter:

     ViewHolder viewHolder = null;
    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        convertView = inflator.inflate(R.layout.row, null);
        viewHolder = new ViewHolder();
        viewHolder.text = (TextView) convertView.findViewById(R.id.label);
        viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.check);
        viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.
            }
        });
        convertView.setTag(viewHolder);
        convertView.setTag(R.id.label, viewHolder.text);
        convertView.setTag(R.id.check, viewHolder.checkbox);
        } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.checkbox.setTag(position); // This line is important.

    viewHolder.text.setText(list.get(position).getName());
    viewHolder.checkbox.setChecked(list.get(position).isSelected());
于 2013-09-24T12:53:45.347 回答