using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
///
/// 通用滑动列表组件
/// 支持动态添加、删除和更新列表项,带有滚动功能
///
public class ScrollableListView : MonoBehaviour
{
[Header("滚动设置")]
public ScrollRect ScrollRect; // 滚动组件
public RectTransform Content; // 内容容器
public GameObject ItemPrefab; // 列表项预制件
[Header("布局设置")]
public float ItemHeight = 80f; // 列表项高度
public float ItemSpacing = 5f; // 列表项间距
public bool AutoResize = true; // 自动调整内容大小
[Header("样式设置")]
public Color AlternateRowColor = new Color(0.9f, 0.9f, 0.9f, 0.3f); // 交替行颜色
public bool UseAlternateRowColors = true; // 是否使用交替行颜色
private List _items = new List();
private VerticalLayoutGroup _layoutGroup;
void Awake()
{
InitializeComponents();
}
private void InitializeComponents()
{
// 如果没有设置ScrollRect,尝试获取
if (ScrollRect == null)
{
ScrollRect = GetComponent();
}
// 如果没有设置Content,尝试从ScrollRect获取
if (Content == null && ScrollRect != null)
{
Content = ScrollRect.content;
}
// 确保Content有VerticalLayoutGroup
if (Content != null)
{
_layoutGroup = Content.GetComponent();
if (_layoutGroup == null)
{
_layoutGroup = Content.gameObject.AddComponent();
}
// 配置VerticalLayoutGroup
_layoutGroup.childControlHeight = false;
_layoutGroup.childControlWidth = true;
_layoutGroup.childForceExpandHeight = false;
_layoutGroup.childForceExpandWidth = false;
_layoutGroup.spacing = ItemSpacing;
_layoutGroup.padding = new RectOffset(5, 5, 5, 5);
}
// 确保ItemPrefab不活跃
if (ItemPrefab != null)
{
ItemPrefab.SetActive(false);
}
}
///
/// 添加列表项
///
public ScrollableListItem AddItem(object data = null)
{
if (ItemPrefab == null || Content == null)
{
Debug.LogError("ItemPrefab or Content is null!");
return null;
}
// 创建新项
GameObject itemGO = Instantiate(ItemPrefab, Content);
itemGO.SetActive(true);
// 设置高度
RectTransform itemRect = itemGO.GetComponent();
if (itemRect != null)
{
itemRect.sizeDelta = new Vector2(itemRect.sizeDelta.x, ItemHeight);
}
// 获取或添加ScrollableListItem组件
ScrollableListItem item = itemGO.GetComponent();
if (item == null)
{
item = itemGO.AddComponent();
}
// 设置数据和索引
item.Initialize(data, _items.Count, this);
_items.Add(item);
// 设置交替行颜色
if (UseAlternateRowColors && _items.Count % 2 == 0)
{
var bgImage = itemGO.GetComponent();
if (bgImage == null)
{
bgImage = itemGO.AddComponent();
}
bgImage.color = AlternateRowColor;
}
// 更新内容大小
if (AutoResize)
{
UpdateContentSize();
}
return item;
}
///
/// 删除指定列表项
///
public void RemoveItem(ScrollableListItem item)
{
if (_items.Remove(item))
{
if (item.gameObject != null)
{
Destroy(item.gameObject);
}
// 更新剩余项的索引
UpdateItemIndices();
if (AutoResize)
{
UpdateContentSize();
}
}
}
///
/// 删除指定索引的列表项
///
public void RemoveItemAt(int index)
{
if (index >= 0 && index < _items.Count)
{
RemoveItem(_items[index]);
}
}
///
/// 清空所有列表项
///
public void ClearItems()
{
foreach (var item in _items)
{
if (item != null && item.gameObject != null)
{
Destroy(item.gameObject);
}
}
_items.Clear();
if (AutoResize)
{
UpdateContentSize();
}
}
///
/// 获取列表项数量
///
public int GetItemCount()
{
return _items.Count;
}
///
/// 获取指定索引的列表项
///
public ScrollableListItem GetItem(int index)
{
if (index >= 0 && index < _items.Count)
{
return _items[index];
}
return null;
}
///
/// 获取所有列表项
///
public List GetAllItems()
{
return new List(_items);
}
///
/// 滚动到指定列表项
///
public void ScrollToItem(ScrollableListItem item)
{
if (ScrollRect == null || Content == null || item == null) return;
int index = _items.IndexOf(item);
if (index >= 0)
{
ScrollToIndex(index);
}
}
///
/// 滚动到指定索引
///
public void ScrollToIndex(int index)
{
if (ScrollRect == null || Content == null || index < 0 || index >= _items.Count) return;
float itemY = index * (ItemHeight + ItemSpacing);
float contentHeight = Content.rect.height;
float viewportHeight = ScrollRect.viewport.rect.height;
if (contentHeight > viewportHeight)
{
float normalizedPosition = 1f - (itemY / (contentHeight - viewportHeight));
normalizedPosition = Mathf.Clamp01(normalizedPosition);
ScrollRect.verticalNormalizedPosition = normalizedPosition;
}
}
///
/// 滚动到顶部
///
public void ScrollToTop()
{
if (ScrollRect != null)
{
ScrollRect.verticalNormalizedPosition = 1f;
}
}
///
/// 滚动到底部
///
public void ScrollToBottom()
{
if (ScrollRect != null)
{
ScrollRect.verticalNormalizedPosition = 0f;
}
}
///
/// 更新内容大小
///
private void UpdateContentSize()
{
if (Content == null) return;
float totalHeight = _items.Count * ItemHeight + (_items.Count - 1) * ItemSpacing + _layoutGroup.padding.top + _layoutGroup.padding.bottom;
Content.sizeDelta = new Vector2(Content.sizeDelta.x, totalHeight);
}
///
/// 更新所有项的索引
///
private void UpdateItemIndices()
{
for (int i = 0; i < _items.Count; i++)
{
if (_items[i] != null)
{
_items[i].SetIndex(i);
}
}
}
///
/// 刷新列表显示
///
public void RefreshList()
{
// 移除已被销毁的项
_items.RemoveAll(item => item == null || item.gameObject == null);
// 更新索引
UpdateItemIndices();
// 更新内容大小
if (AutoResize)
{
UpdateContentSize();
}
}
}
///
/// 滚动列表项基类
///
public class ScrollableListItem : MonoBehaviour
{
public object Data { get; private set; }
public int Index { get; private set; }
public ScrollableListView ListView { get; private set; }
public event Action OnItemClicked;
public event Action OnItemSelected;
private Button _button;
private Toggle _toggle;
void Awake()
{
// 获取按钮组件
_button = GetComponent