using System; using System.Collections.Generic; namespace AlicizaX.UI { /// /// RecyclerView 的通用适配器,支持数据绑定、选中状态和列表操作 /// /// 数据类型,必须实现 ISimpleViewData 接口 public class Adapter : IAdapter where T : ISimpleViewData { protected RecyclerView recyclerView; protected List list; protected Action onItemClick; protected int choiceIndex = -1; /// /// 当前选中项的索引 /// public int ChoiceIndex { get => choiceIndex; set { SetChoiceIndex(value); } } /// /// 构造函数 /// /// RecyclerView 实例 public Adapter(RecyclerView recyclerView) : this(recyclerView, new List(), null) { } /// /// 构造函数 /// /// RecyclerView 实例 /// 数据列表 public Adapter(RecyclerView recyclerView, List list) : this(recyclerView, list, null) { } /// /// 构造函数 /// /// RecyclerView 实例 /// 数据列表 /// 列表项点击回调 public Adapter(RecyclerView recyclerView, List list, Action onItemClick) { this.recyclerView = recyclerView; this.list = list; this.onItemClick = onItemClick; } /// /// 获取列表项总数 /// public virtual int GetItemCount() { return list == null ? 0 : list.Count; } /// /// 获取实际数据项数量 /// public virtual int GetRealCount() { return GetItemCount(); } /// /// 获取指定索引位置的视图名称 /// public virtual string GetViewName(int index) { return ""; } /// /// 绑定视图持有者与数据 /// public virtual void OnBindViewHolder(ViewHolder viewHolder, int index) { if (index < 0 || index >= GetItemCount()) return; T data = list[index]; viewHolder.BindViewData(data); viewHolder.BindItemClick(data, t => { SetChoiceIndex(index); onItemClick?.Invoke(data); }); viewHolder.BindChoiceState(index == choiceIndex); } /// /// 通知数据已更改 /// public virtual void NotifyDataChanged() { recyclerView.RequestLayout(); recyclerView.Refresh(); } /// /// 设置数据列表并刷新视图 /// /// 新的数据列表 public virtual void SetList(List list) { this.list = list; recyclerView.Reset(); NotifyDataChanged(); } /// /// 获取指定索引的数据 /// /// 数据索引 /// 数据对象,索引无效时返回 default public T GetData(int index) { if (index < 0 || index >= GetItemCount()) return default; return list[index]; } /// /// 添加单个数据项 /// /// 要添加的数据项 public void Add(T item) { list.Add(item); NotifyDataChanged(); } /// /// 批量添加数据项 /// /// 要添加的数据集合 public void AddRange(IEnumerable collection) { list.AddRange(collection); NotifyDataChanged(); } /// /// 在指定位置插入数据项 /// /// 插入位置 /// 要插入的数据项 public void Insert(int index, T item) { list.Insert(index, item); NotifyDataChanged(); } /// /// 在指定位置批量插入数据项 /// /// 插入位置 /// 要插入的数据集合 public void InsertRange(int index, IEnumerable collection) { list.InsertRange(index, collection); NotifyDataChanged(); } /// /// 移除指定的数据项 /// /// 要移除的数据项 public void Remove(T item) { int index = list.IndexOf(item); RemoveAt(index); } /// /// 移除指定索引位置的数据项 /// /// 要移除的索引 public void RemoveAt(int index) { if (index < 0 || index >= GetItemCount()) return; list.RemoveAt(index); NotifyDataChanged(); } /// /// 移除指定范围的数据项 /// /// 起始索引 /// 移除数量 public void RemoveRange(int index, int count) { list.RemoveRange(index, count); NotifyDataChanged(); } /// /// 移除所有符合条件的数据项 /// /// 匹配条件 public void RemoveAll(Predicate match) { list.RemoveAll(match); NotifyDataChanged(); } /// /// 清空所有数据 /// public void Clear() { list.Clear(); NotifyDataChanged(); } /// /// 反转指定范围的数据项顺序 /// /// 起始索引 /// 反转数量 public void Reverse(int index, int count) { list.Reverse(index, count); NotifyDataChanged(); } /// /// 反转所有数据项顺序 /// public void Reverse() { list.Reverse(); NotifyDataChanged(); } /// /// 使用指定的比较器排序数据 /// /// 比较器 public void Sort(Comparison comparison) { list.Sort(comparison); NotifyDataChanged(); } /// /// 设置列表项点击回调 /// /// 点击回调 public void SetOnItemClick(Action onItemClick) { this.onItemClick = onItemClick; } /// /// 设置选中项索引 /// /// 要选中的索引 protected void SetChoiceIndex(int index) { if (index == choiceIndex) return; if (choiceIndex != -1) { if (TryGetViewHolder(choiceIndex, out var viewHolder)) { viewHolder.BindChoiceState(false); } } choiceIndex = index; if (choiceIndex != -1) { if (TryGetViewHolder(choiceIndex, out var viewHolder)) { viewHolder.BindChoiceState(true); } } } /// /// 尝试获取指定索引的视图持有者 /// /// 数据索引 /// 输出的视图持有者 /// 是否成功获取 private bool TryGetViewHolder(int index, out ViewHolder viewHolder) { viewHolder = recyclerView.ViewProvider.GetViewHolder(index); return viewHolder != null; } } }