ListView滚动时为何会重置已修改的列表项?
解决ListView点击更新后滚动恢复默认值的问题
嘿,这个问题我太熟了!本质是你只改了UI上的显示,没同步更新数据源,加上ListView的复用机制在捣乱,给你一步步解决:
1. 先给实体类加状态字段
你的CategoryPreviewClass现在只有名称和ID,没有存储修改后的状态(比如是否选中、修改后的名称),所以滚动时Adapter只能拿到原始数据。先扩展实体类:
public class CategoryPreviewClass { public string CategoryName { get; set; } public string CategoryID { get; set; } // 新增字段存状态,比如是否选中(根据你的需求调整) public bool IsSelected { get; set; } = false; // 如果是修改名称,就加个显示用的字段 public string DisplayName { get; set; } }
2. 点击列表项时,更新数据源+通知Adapter
点击时别只改View,要找到对应的数据对象修改,然后告诉Adapter数据变了:
// 假设你的ListView是listView,数据源是List<CategoryPreviewClass> categoryList listView.ItemClick += (sender, e) => { // 获取点击位置的实体对象 var targetCategory = categoryList[e.Position]; // 这里根据你的需求修改状态,比如切换选中状态 targetCategory.IsSelected = !targetCategory.IsSelected; // 如果是改名称:targetCategory.DisplayName = "修改后的名称"; // 关键!通知Adapter更新UI yourCustomAdapter.NotifyDataSetChanged(); };
3. 修改Adapter的GetView方法,用最新数据源渲染
ListView滚动时会复用View,所以GetView里必须从数据源取最新状态,不能用默认值:
public override View GetView(int position, View convertView, ViewGroup parent) { View row = convertView; ViewHolder holder; // 复用View+ViewHolder优化性能 if (row == null) { row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.你的列表项布局, parent, false); holder = new ViewHolder(); holder.categoryNameTv = row.FindViewById<TextView>(Resource.Id.tv_category_name); // 其他控件比如CheckBox、ImageView也放这里 row.Tag = holder; } else { holder = (ViewHolder)row.Tag; } // 拿到当前位置的最新数据 var currentItem = categoryList[position]; // 根据最新数据设置UI if (currentItem.IsSelected) { holder.categoryNameTv.SetTextColor(Color.Red); // 选中样式 // 比如如果有CheckBox:holder.selectCb.Checked = true; } else { holder.categoryNameTv.SetTextColor(Color.Black); // 默认样式 // holder.selectCb.Checked = false; } // 如果是修改名称,优先用DisplayName,没有就用原始名称 holder.categoryNameTv.Text = currentItem.DisplayName ?? currentItem.CategoryName; return row; } // ViewHolder类,避免重复查找控件 private class ViewHolder { public TextView categoryNameTv; // 其他控件声明,比如CheckBox selectCb; }
为什么之前会出问题?
ListView的convertView是复用机制,滚动时会把滑出屏幕的View重新拿来用,如果你没把修改后的状态存在数据源里,GetView每次都会从原始的、未修改的CategoryPreviewClass对象取数据,自然就恢复默认了。核心原则:UI的状态永远从数据源读取,修改UI前先改数据源。
内容的提问来源于stack exchange,提问作者testsc
相关产品推荐
相关产品推荐

