123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- 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> GetNextItem;
- public Func<int, VirtualScrollRectItem> GetPreviousItem;
- public Action<int, VirtualScrollRectItem> OnSaveItem;
- public int FirstIndex;
- public int LastIndex;
- public bool Inited;
- public HorizontalOrVerticalLayoutGroup LayoutGroup;
- public int MaxRollAmount;
- public int MaxChildAmount;
- public bool NextPageLock;
- public bool PreviousPageLock;
- 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)
- {
- if (!PreviousPageLock)
- {
- Vector2 widthAndHeight = PreviousPage();
- Roll(new Vector2(-widthAndHeight.x, 0));
- }
- OnHorizontalGreaterEqual1.SafeInvoke();
- }
- if (horizontalNormalizedPosition >= 1)
- {
- if (!NextPageLock)
- {
- Vector2 widthAndHeight = NextPage();
- Roll(new Vector2(widthAndHeight.x, 0));
- }
- OnHorizontalLessEqual0.SafeInvoke();
- }
- }
- else if (!horizontal && vertical)
- {
- if (verticalNormalizedPosition >= 1)
- {
- if (!PreviousPageLock)
- {
- Vector2 widthAndHeight = PreviousPage();
- Roll(new Vector2(0, widthAndHeight.y));
- }
- OnVerticalGreaterEqual1.SafeInvoke();
- }
- if (verticalNormalizedPosition <= 0)
- {
- if (!NextPageLock)
- {
- Vector2 widthAndHeight = NextPage();
- Roll(new Vector2(0, -widthAndHeight.y));
- }
- OnVerticalLessEqual0.SafeInvoke();
- }
- }
- }
- public void Init(int maxRollAmount, int maxChildAmount, Func<int, VirtualScrollRectItem> getNextItem, Func<int, VirtualScrollRectItem> getPreviousItem, Action<int, VirtualScrollRectItem> onSaveItem)
- {
- Inited = true;
- MaxRollAmount = maxRollAmount;
- MaxChildAmount = maxChildAmount;
- LayoutGroup = content.GetComponent<HorizontalOrVerticalLayoutGroup>();
- GetNextItem = getNextItem;
- GetPreviousItem = getPreviousItem;
- OnSaveItem = onSaveItem;
- }
- 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 void InsertChild(int siblingIndex, int dataIndex, VirtualScrollRectItem item)
- {
- Children.Insert(siblingIndex, item);
- ChildrenDataIndexDictionary.Add(item, dataIndex);
- item.transform.SetSiblingIndex(siblingIndex);
- FirstIndex = ChildrenDataIndexDictionary[Children[0]];
- LastIndex = ChildrenDataIndexDictionary[Children.Back(0)];
- }
- public void InsertChildToFirst(int dataIndex, VirtualScrollRectItem item)
- {
- InsertChild(0, dataIndex, item);
- }
- public void InsertChildToLast(int dataIndex, VirtualScrollRectItem item)
- {
- InsertChild(Children.Count, dataIndex, item);
- }
- public 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 = GetNextItem.Invoke(dataIndex);
- if (item == null)
- {
- break;
- }
- else
- {
- if (Children.Count >= MaxChildAmount)
- {
- SaveFirstChild();
- rolledItems.Add(item);
- }
- InsertChildToLast(dataIndex, item);
- }
- }
- 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 Vector2 PreviousPage()
- {
- //Debug.LogWarning("PreviousPage");
- List<VirtualScrollRectItem> rolledItems = new List<VirtualScrollRectItem>();
- for (int i = 0; i < MaxRollAmount; i++)
- {
- VirtualScrollRectItem item = GetPreviousItem.Invoke(FirstIndex-1);
- if (item == null)
- {
- break;
- }
- else
- {
- if (Children.Count >= MaxChildAmount)
- {
- SaveLastChild();
- rolledItems.Add(item);
- }
- InsertChildToFirst(FirstIndex-1, item);
- }
- }
- 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;
- }
- }
|