我正在使用listview自定义适配器,通过行单击我正在更改行颜色。但是当我再次向上滚动机器人时,它的位置不正确。它会改变其他行的颜色...
public override View GetView(int position, View convertView, ViewGroup parent)
{
DataViewHolder holder = null;
if (convertView == null)
{
convertView = LayoutInflater.From(mContext).Inflate(Resource.Layout.TableItems, null, false);
holder = new DataViewHolder();
holder.txtDescription = convertView.FindViewById<TextView>(Resource.Id.txtDescription);
holder.txtDescription.Click += delegate
{
holder.txtDescription.SetBackgroundColor(Color.Red);
};
convertView.Tag = holder;
}
else
{
holder = convertView.Tag as DataViewHolder;
}
holder.txtDescription.Text = mitems[position].Description;
return convertView;
}
public class DataViewHolder : Java.Lang.Object
{
public TextView txtDescription { get; set; }
}
看起来它没有在内存中保留特定的行情况。
不要直接更改单击处理程序中的颜色,而是更改适配器从中提取的数据,并在再次调用 GetView 时使用该数据更改颜色。
ListView
回收用于优化滚动的视图,而是只期望视图表示数据。如果直接更改一个视图的颜色,则该视图将被回收,您将看到具有不同背景颜色的"另一个视图"(数据的另一部分(。
所以总结一下:给每个数据点一个颜色属性,并使用它来设置GetView
中每个视图的颜色,更改数据并通知适配器有关数据的更改。
编辑
我从未使用过Xamarin,但也许这样的东西会起作用
public override View GetView(int position, View convertView, ViewGroup parent)
{
DataViewHolder holder = null;
if (convertView == null)
{
convertView = LayoutInflater.From(mContext).Inflate(Resource.Layout.TableItems, null, false);
holder = new DataViewHolder();
holder.txtDescription = convertView.FindViewById<TextView>(Resource.Id.txtDescription);
holder.txtDescription.Click += delegate
{
// instead of setting the color directly here, just modify the data
(holder.txtDescription.Tag as ItemType).ItemColor = Color.Red
notifyDataSetChanged();
};
convertView.Tag = holder;
}
else
{
holder = convertView.Tag as DataViewHolder;
}
holder.txtDescription.Text = mitems[position].Description;
holder.txtDescription.Tag = mitems[position]; // this so that the click handler knows which item to modify
holder.txtDescription.SetBackgroundColor(mitems[position].ItemColor);
return convertView;
}
public class DataViewHolder : Java.Lang.Object
{
public TextView txtDescription { get; set; }
}
ListView
会重用项目布局,您可以使用List
和View.Tag
来避免重用引起的问题。
我已经在github上发布了我的演示。