我一直在尝试创建一个多选的ListView,就像在这个链接中查看图片一样: picture 当用户取消选中左上角的复选框时,listviewItem布局必须更改为未选中状态。 现在我用它:
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;
}
}
在活动中:
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);
}
但我遇到了问题: 当用户取消选中复选框时,如何更改布局? 我试过在Adapter中处理CheckedChange事件,但我怎么知道这个ListViewItem的位置? 我的解决方案在我看来不是很好,请给我建议我怎样才能做得更好。 我想知道你是否向我展示了一个关于C#或Java的简单例子。 感谢
答案 0 :(得分:0)
我做了一个可能对你有帮助的简单例子。它是一个列表,每个列表项都有一个TextView和CheckBox。文本视图显示绿色或红色的位置,具体取决于是否选中复选框。它是您问题的简化版本。不知道它是否是最好的解决方案,但它会起作用。
唯一需要注意的事项。由于绑定复选框时会重复使用视图,因此它可以触发CheckedChange事件。这就是在进行绑定时首先更改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; }
}
}
}