123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
- public class VirtualScrollRectPlus : ScrollRect
- {
- #region Config //对象池需要外部实现
- public Action OnVerticalLessEqual0;
- public Action OnVerticalGreaterEqual1;
- public Action OnHorizontalLessEqual0;
- public Action OnHorizontalGreaterEqual1;
- public Func<int, VirtualScrollRectItem> OnGetNextItem;
- public Func<int, VirtualScrollRectItem> OnGetPreviousItem;
- public Action<int, VirtualScrollRectItem> OnSaveItem;
- public int FirstIndex;
- public int LastIndex;
- public bool Inited;
- public HorizontalOrVerticalLayoutGroup LayoutGroup;
- public int MaxRollAmount;
- public int MaxChildAmount;
- public List<VirtualScrollRectItem> Children = new List<VirtualScrollRectItem>();
- public Dictionary<VirtualScrollRectItem, int> ChildrenDataIndexDictionary = new Dictionary<VirtualScrollRectItem, int>();
- #endregion
- public override void OnDrag(PointerEventData eventData)
- {
- base.OnDrag(eventData);
- if (!Inited)
- {
- return;
- }
- if (horizontal && !vertical)
- {
- if (horizontalNormalizedPosition <= 0)
- {
- //Vector2 widthAndHeight = PreviousPage();
- //Roll(new Vector2(-widthAndHeight.x, 0));
- PreviousHorizontalPage();
- OnHorizontalGreaterEqual1.SafeInvoke();
- }
- if (horizontalNormalizedPosition >= 1)
- {
- //Vector2 widthAndHeight = NextPage();
- //Roll(new Vector2(widthAndHeight.x, 0));
- NextHorizontalPage();
- OnHorizontalLessEqual0.SafeInvoke();
- }
- }
- else if (!horizontal && vertical)
- {
- if (verticalNormalizedPosition >= 1)
- {
- //Vector2 widthAndHeight = PreviousPage();
- //Roll(new Vector2(0, widthAndHeight.y));
- PreviousVerticalPage();
- OnVerticalGreaterEqual1.SafeInvoke();
- }
- if (verticalNormalizedPosition <= 0)
- {
- //Vector2 widthAndHeight = NextPage();
- //Roll(new Vector2(0, -widthAndHeight.y));
- NextVerticalPage();
- OnVerticalLessEqual0.SafeInvoke();
- }
- }
- }
- public void Init(int maxRollAmount, int maxChildAmount, Func<int, VirtualScrollRectItem> getNextItem = null, Func<int, VirtualScrollRectItem> getPreviousItem = null, Action<int, VirtualScrollRectItem> onSaveItem = null)
- {
- Inited = true;
- MaxRollAmount = maxRollAmount;
- MaxChildAmount = maxChildAmount;
- LayoutGroup = content.GetComponent<HorizontalOrVerticalLayoutGroup>();
- OnGetNextItem = getNextItem;
- OnGetPreviousItem = getPreviousItem;
- OnSaveItem = onSaveItem;
- }
- public void SaveAllChild()
- {
- while (Children.Count > 0)
- {
- SaveFirstChild();
- }
- }
- public void SaveChild(VirtualScrollRectItem item)
- {
- int dataIndex = ChildrenDataIndexDictionary[item];
- OnSaveItem.Invoke(dataIndex, item);
- Children.Remove(item);
- ChildrenDataIndexDictionary.Remove(item);
- if (Children.Count > 0)
- {
- FirstIndex = ChildrenDataIndexDictionary[Children[0]];
- LastIndex = ChildrenDataIndexDictionary[Children.Back(0)];
- }
- else
- {
- FirstIndex = 0;
- LastIndex = 0;
- }
- }
- public void SaveFirstChild()
- {
- SaveChild(Children[0]);
- }
- public void SaveLastChild()
- {
- SaveChild(Children.Back(0));
- }
- public VirtualScrollRectItem InsertChild(int siblingIndex, int dataIndex, VirtualScrollRectItem item, bool saveItem = false, int savaSiblingIndex = 0)
- {
- VirtualScrollRectItem savedItem = null;
- if (saveItem && Children.Count >= MaxChildAmount)
- {
- if (savaSiblingIndex == -1)
- {
- savedItem = Children.Back(0);
- }
- else
- {
- savedItem = Children[savaSiblingIndex];
- }
- if (siblingIndex == Children.Count)
- {
- siblingIndex--;
- }
- SaveChild(savedItem);
- }
- Children.Insert(siblingIndex, item);
- ChildrenDataIndexDictionary.Add(item, dataIndex);
- item.transform.SetSiblingIndex(siblingIndex);
- FirstIndex = ChildrenDataIndexDictionary[Children[0]];
- LastIndex = ChildrenDataIndexDictionary[Children.Back(0)];
- return savedItem;
- }
- public VirtualScrollRectItem InsertChildToFirst(int dataIndex, VirtualScrollRectItem item, bool saveItem = false, int savaSiblingIndex = 0)
- {
- return InsertChild(0, dataIndex, item, saveItem, savaSiblingIndex);
- }
- public VirtualScrollRectItem InsertChildToLast(int dataIndex, VirtualScrollRectItem item, bool saveItem = false, int savaSiblingIndex = 0)
- {
- return InsertChild(Children.Count, dataIndex, item, saveItem, savaSiblingIndex);
- }
- public void NextVerticalPage()
- {
- Vector2 widthAndHeight = NextPage();
- Roll(new Vector2(0, -widthAndHeight.y));
- }
- public void NextHorizontalPage()
- {
- Vector2 widthAndHeight = NextPage();
- Roll(new Vector2(widthAndHeight.x, 0));
- }
- public void PreviousVerticalPage()
- {
- Vector2 widthAndHeight = PreviousPage();
- Roll(new Vector2(0, widthAndHeight.y));
- }
- public void PreviousHorizontalPage()
- {
- Vector2 widthAndHeight = PreviousPage();
- Roll(new Vector2(-widthAndHeight.x, 0));
- }
- private Vector2 NextPage()
- {
- //Debug.LogWarning("NextPage");
- List<VirtualScrollRectItem> rolledItems = new List<VirtualScrollRectItem>();
- for (int i = 0; i < MaxRollAmount; i++)
- {
- int dataIndex = Children.Count == 0 ? 0 : LastIndex + 1;
- VirtualScrollRectItem item = OnGetNextItem.Invoke(dataIndex);
- if (item == null)
- {
- break;
- }
- else
- {
- VirtualScrollRectItem savedItem = InsertChildToLast(dataIndex, item, true, 0);
- if (savedItem != null)
- {
- rolledItems.Add(savedItem);
- }
- }
- }
-
- Vector2 widthAndHeight = new Vector2(rolledItems.MySum(item => item.RectTransform.rect.width), rolledItems.MySum(item => item.RectTransform.rect.height));
- widthAndHeight += new Vector2(LayoutGroup.spacing, LayoutGroup.spacing) * Mathf.Max(rolledItems.Count - 1, 0);
- return widthAndHeight;
- }
- private Vector2 PreviousPage()
- {
- //Debug.LogWarning("PreviousPage");
- List<VirtualScrollRectItem> rolledItems = new List<VirtualScrollRectItem>();
- for (int i = 0; i < MaxRollAmount; i++)
- {
- VirtualScrollRectItem item = OnGetPreviousItem.Invoke(FirstIndex-1);
- if (item == null)
- {
- break;
- }
- else
- {
- VirtualScrollRectItem savedItem = InsertChildToFirst(FirstIndex-1, item, true, -1);
- if (savedItem != null)
- {
- rolledItems.Add(savedItem);
- }
- }
- }
- Vector2 widthAndHeight = new Vector2(rolledItems.MySum(item => item.RectTransform.rect.width), rolledItems.MySum(item => item.RectTransform.rect.height));
- widthAndHeight += new Vector2(LayoutGroup.spacing, LayoutGroup.spacing)*Mathf.Max(rolledItems.Count - 1, 0);
- return widthAndHeight;
- }
- public void Roll(Vector2 contentOffset)
- {
- m_ContentStartPosition += contentOffset;
- }
- }
|