我使用自定义列表视图和复选框。当我向下滚动列表视图时,我会看到一些自动选中的复选框。当我向上滚动时,某些已选中的用户已取消选中。
class MyListViewAdapterExtras :BaseAdapter<ExtrasPreviewClass>
{
public List<ExtrasPreviewClass> mitems;
private Context mContext;
public MyListViewAdapterExtras(Context context, List<ExtrasPreviewClass> items)
{
mitems = items;
mContext = context;
}
public override int Count
{
get
{
return mitems.Count;
}
}
public override long GetItemId(int position)
{
return position;
}
public override ExtrasPreviewClass this[int position]
{
get
{
return mitems[position];
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
row = LayoutInflater.From(mContext).Inflate(Resource.Layout.ExtrasPreview, null, false);
}
TextView txtName = row.FindViewById<TextView>(Resource.Id.txtName);
txtName .Text = mitems[position].Name;
CheckBox txtCheckBox= row.FindViewById<CheckBox>(Resource.Id.txtCheckBox);
txtCheckBox.Text = Convert.ToString(mitems[position].CheckBox);
return row;
}
有什么方法可以解决这个问题吗?
答案 0 :(得分:0)
在GetView()
方法中,如果convertView
不是null
,那么您将重用View
。该视图将具有来自其分配的任何位置的数据。如果您不更改数据,它将显示在不同的广告位中并导致您看到的内容。
要解决此问题,您需要确保GetView()
将View
的所有数据设置为指定位置的正确值,无论View
是否重复使用
以下是我认为relevant example的链接。我已经提取了getView()
代码并发表了评论。我希望这会有所帮助。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Modified to reuse convertView
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(R.layout.row, parent, false);
}
TextView name = (TextView) convertView.findViewById(R.id.textView1);
// Find the checkBox view
CheckBox cb = (CheckBox) convertView.findViewById(R.id.checkBox1);
name.setText(modelItems[position].getName());
// Set the checkBox as "checked" or "unchecked" depending upon our internal
// data structure. Here it is "modelItems[]". If we don't do this, then the checkBox
// will be set to whatever it was set to if convertView is reused.
if (modelItems[position].getValue() == 1)
cb.setChecked(true);
else
cb.setChecked(false);
return convertView;
}
答案 1 :(得分:0)
我使用自定义列表视图和复选框。当我向下滚动列表视图时,我会看到一些自动选中的复选框。当我向上滚动时,某些已选中的用户已取消选中。
正如@Cheticamp所说,ListView中的视图将在滚动期间重复使用,您需要每次getView
调用时更新视图。
从您的代码中,您已经有了文字,但没有更新ischecked
州。为实现这一目标,我们需要遵循以下步骤:
更新Model类(ExtrasPreviewClass
)以添加bool字段以存储isChecked
状态:
public class ExtrasPreviewClass
{
public ExtrasPreviewClass(string name, string checkbox)
{
this.Name = name;
this.CheckBox = checkbox;
this.IsChecked = false;
}
public String Name { get; set; }
public String CheckBox { get; set; }
public bool IsChecked { get; set; }
}
更新适配器中的GetView
方法,并在GetView
下面添加一个事件监听器类:
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
row = LayoutInflater.From(mContext).Inflate(Resource.Layout.ItemView, null, false);
}
TextView txtName = row.FindViewById<TextView>(Resource.Id.txtName);
txtName.Text = mitems[position].Name;
CheckBox txtCheckBox = row.FindViewById<CheckBox>(Resource.Id.txtCheckBox);
txtCheckBox.Text = Convert.ToString(mitems[position].CheckBox);
//SetOnCheckedChangeListener must be set before txtCheckBox.Checked = mitems[position].IsChecked
txtCheckBox.SetOnCheckedChangeListener(new CheckChangeListener(position, ref mitems));
txtCheckBox.Checked = mitems[position].IsChecked;
Console.WriteLine("Set the CheckBox " + position + " to "+ mitems[position].IsChecked);
return row;
}
public class CheckChangeListener : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener
{
int position;
List<ExtrasPreviewClass> items;
public CheckChangeListener(int position,ref List<ExtrasPreviewClass> items)
{
this.position = position;
this.items = items;
}
public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)
{
items[position].IsChecked = isChecked;
Console.WriteLine("Set the " + position + " IsChecked to " + isChecked);
}
}
注意:txtCheckBox.SetOnCheckedChangeListener
之前应调用txtCheckBox.Checked = mitems[position].IsChecked
。否则,你会得到意想不到的行为。
更新:可以更新ChangeCheckListener
旁边的视图,你需要像下面那样修改监听器:
public class CheckChangeListener2 : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener
{
int position;
List<ExtrasPreviewClass> items;
View row;
public CheckChangeListener2(int position, ref List<ExtrasPreviewClass> items,View row)
{
this.position = position;
this.items = items;
this.row = row;
}
public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)
{
items[position].IsChecked = isChecked;
TextView txtName = row.FindViewById<TextView>(Resource.Id.txtName);
//update the name
txtName.Text = items[position].Name;
Console.WriteLine("Set the " + position + " IsChecked to " + isChecked);
}
}