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