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