com.alicizax.unity.ui.exten.../Runtime/RecyclerView/ViewProvider/ViewProvider.cs
2026-03-11 14:18:07 +08:00

190 lines
6.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using UnityEngine;
namespace AlicizaX.UI
{
/// <summary>
/// 提供和管理 ViewHolder
/// 负责 ViewHolder 的创建、回收和复用
/// </summary>
public abstract class ViewProvider
{
private readonly List<ViewHolder> viewHolders = new();
/// <summary>
/// 获取或设置数据适配器
/// </summary>
public IAdapter Adapter { get; set; }
/// <summary>
/// 获取或设置布局管理器
/// </summary>
public LayoutManager LayoutManager { get; set; }
/// <summary>
/// 获取当前所有活动的 ViewHolder 列表
/// </summary>
public List<ViewHolder> ViewHolders => viewHolders;
protected RecyclerView recyclerView;
protected ViewHolder[] templates;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="recyclerView">关联的 RecyclerView 实例</param>
/// <param name="templates">ViewHolder 模板数组</param>
public ViewProvider(RecyclerView recyclerView, ViewHolder[] templates)
{
this.recyclerView = recyclerView;
this.templates = templates;
}
/// <summary>
/// 根据视图名称获取对应的模板(抽象方法,由子类实现)
/// </summary>
/// <param name="viewName">视图名称</param>
/// <returns>对应的 ViewHolder 模板</returns>
public abstract ViewHolder GetTemplate(string viewName);
/// <summary>
/// 获取所有模板(抽象方法,由子类实现)
/// </summary>
/// <returns>所有 ViewHolder 模板数组</returns>
public abstract ViewHolder[] GetTemplates();
/// <summary>
/// 从对象池中分配一个 ViewHolder抽象方法由子类实现
/// </summary>
/// <param name="viewName">视图名称</param>
/// <returns>分配的 ViewHolder 实例</returns>
public abstract ViewHolder Allocate(string viewName);
/// <summary>
/// 将 ViewHolder 回收到对象池(抽象方法,由子类实现)
/// </summary>
/// <param name="viewName">视图名称</param>
/// <param name="viewHolder">要回收的 ViewHolder</param>
public abstract void Free(string viewName, ViewHolder viewHolder);
/// <summary>
/// 重置 ViewProvider 状态(抽象方法,由子类实现)
/// </summary>
public abstract void Reset();
/// <summary>
/// 创建指定索引的 ViewHolder
/// 从对象池中获取或创建新的 ViewHolder并进行布局和数据绑定
/// </summary>
/// <param name="index">数据索引</param>
public void CreateViewHolder(int index)
{
for (int i = index; i < index + LayoutManager.Unit; i++)
{
if (i > Adapter.GetItemCount() - 1) break;
string viewName = Adapter.GetViewName(i);
var viewHolder = Allocate(viewName);
viewHolder.Name = viewName;
viewHolder.Index = i;
viewHolders.Add(viewHolder);
LayoutManager.Layout(viewHolder, i);
Adapter.OnBindViewHolder(viewHolder, i);
}
}
/// <summary>
/// 移除指定索引的 ViewHolder
/// 将 ViewHolder 从活动列表中移除并回收到对象池
/// </summary>
/// <param name="index">数据索引</param>
public void RemoveViewHolder(int index)
{
for (int i = index; i < index + LayoutManager.Unit; i++)
{
if (i > Adapter.GetItemCount() - 1) break;
int viewHolderIndex = GetViewHolderIndex(i);
if (viewHolderIndex < 0 || viewHolderIndex >= viewHolders.Count) return;
var viewHolder = viewHolders[viewHolderIndex];
viewHolders.RemoveAt(viewHolderIndex);
viewHolder.OnRecycled();
Free(viewHolder.Name, viewHolder);
}
}
/// <summary>
/// 根据数据的下标获取对应的 ViewHolder
/// </summary>
/// <param name="index">数据的下标</param>
/// <returns></returns>
public ViewHolder GetViewHolder(int index)
{
foreach (var viewHolder in viewHolders)
{
if (viewHolder.Index == index)
{
return viewHolder;
}
}
return null;
}
/// <summary>
/// 根据数据的下标获取 ViewHolder 的下标
/// </summary>
/// <param name="index">数据的下标</param>
/// <returns></returns>
public int GetViewHolderIndex(int index)
{
for (int i = 0; i < viewHolders.Count; i++)
{
if (viewHolders[i].Index == index)
{
return i;
}
}
return -1;
}
/// <summary>
/// 清空所有 ViewHolder
/// 将所有活动的 ViewHolder 回收到对象池并清空列表
/// </summary>
public void Clear()
{
foreach (var viewHolder in viewHolders)
{
Free(viewHolder.Name, viewHolder);
}
viewHolders.Clear();
}
/// <summary>
/// 计算 ViewHolder 的尺寸
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Vector2 CalculateViewSize(int index)
{
Vector2 size = GetTemplate(Adapter.GetViewName(index)).SizeDelta;
return size;
}
/// <summary>
/// 获取数据项总数
/// </summary>
/// <returns>数据项总数,如果没有适配器则返回 0</returns>
public int GetItemCount()
{
return Adapter == null ? 0 : Adapter.GetItemCount();
}
}
}