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;
}
}
}