| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- using UnityEngine;
- using UnityEngine.UI;
- using System.Collections;
- using ET;
- namespace UnityEngine.UI
- {
- //[AddComponentMenu("UI/Loop Vertical Scroll Rect", 51)]
- [DisallowMultipleComponent]
- public class LoopVerticalScrollRect : LoopScrollRect
- {
- LoopVerticalScrollRect()
- {
- direction = LoopScrollRectDirection.Vertical;
- }
- protected override float GetSize(RectTransform item, bool includeSpacing)
- {
- float size = includeSpacing ? contentSpacing : 0;
- if (m_GridLayout != null)
- {
- size += m_GridLayout.cellSize.y;
- }
- else
- {
- size += LayoutUtility.GetPreferredHeight(item);
- }
- size *= m_Content.localScale.y;
- return size;
- }
- protected override float GetDimension(Vector2 vector)
- {
- return vector.y;
- }
-
- protected override float GetAbsDimension(Vector2 vector)
- {
- return vector.y;
- }
- protected override Vector2 GetVector(float value)
- {
- return new Vector2(0, value);
- }
- protected override void Awake()
- {
- base.Awake();
- if (m_Content)
- {
- GridLayoutGroup layout = m_Content.GetComponent<GridLayoutGroup>();
- if (layout != null && layout.constraint != GridLayoutGroup.Constraint.FixedColumnCount)
- {
- Debug.LogError($"[LoopScrollRect] {this.gameObject.name} 不支持的GridLayoutGroup约束 必须使用 FixedColumnCount",this);
- }
- }
- }
- protected override async ETTask<(bool,Bounds,Bounds)> UpdateItems(Bounds viewBounds, Bounds contentBounds)
- {
- bool changed = false;
- // special case: handling move several page in one frame
- if ((viewBounds.size.y < contentBounds.min.y - viewBounds.max.y) && itemTypeEnd > itemTypeStart)
- {
- int maxItemTypeStart = -1;
- if (totalCount >= 0)
- {
- maxItemTypeStart = Mathf.Max(0, totalCount - (itemTypeEnd - itemTypeStart));
- }
- float currentSize = contentBounds.size.y;
- float elementSize = (currentSize - contentSpacing * (CurrentLines - 1)) / CurrentLines;
- ReturnToTempPool(true, itemTypeEnd - itemTypeStart);
- itemTypeStart = itemTypeEnd;
- int offsetCount = Mathf.FloorToInt((contentBounds.min.y - viewBounds.max.y) / (elementSize + contentSpacing));
- if (maxItemTypeStart >= 0 && itemTypeStart + offsetCount * contentConstraintCount > maxItemTypeStart)
- {
- offsetCount = Mathf.FloorToInt((float)(maxItemTypeStart - itemTypeStart) / contentConstraintCount);
- }
- itemTypeStart += offsetCount * contentConstraintCount;
- if (totalCount >= 0)
- {
- itemTypeStart = Mathf.Max(itemTypeStart, 0);
- }
- itemTypeEnd = itemTypeStart;
- float offset = offsetCount * (elementSize + contentSpacing);
- m_Content.anchoredPosition -= new Vector2(0, offset + (reverseDirection ? 0 : currentSize));
- contentBounds.center -= new Vector3(0, offset + currentSize / 2, 0);
- contentBounds.size = Vector3.zero;
- changed = true;
- }
- if ((viewBounds.min.y - contentBounds.max.y > viewBounds.size.y) && itemTypeEnd > itemTypeStart)
- {
- float currentSize = contentBounds.size.y;
- float elementSize = (currentSize - contentSpacing * (CurrentLines - 1)) / CurrentLines;
- ReturnToTempPool(false, itemTypeEnd - itemTypeStart);
- itemTypeEnd = itemTypeStart;
- int offsetCount = Mathf.FloorToInt((viewBounds.min.y - contentBounds.max.y) / (elementSize + contentSpacing));
- if (totalCount >= 0 && itemTypeStart - offsetCount * contentConstraintCount < 0)
- {
- offsetCount = Mathf.FloorToInt((float)(itemTypeStart) / contentConstraintCount);
- }
- itemTypeStart -= offsetCount * contentConstraintCount;
- if (totalCount >= 0)
- {
- itemTypeStart = Mathf.Max(itemTypeStart, 0);
- }
- itemTypeEnd = itemTypeStart;
- float offset = offsetCount * (elementSize + contentSpacing);
- m_Content.anchoredPosition += new Vector2(0, offset + (reverseDirection ? currentSize : 0));
- contentBounds.center += new Vector3(0, offset + currentSize / 2, 0);
- contentBounds.size = Vector3.zero;
- changed = true;
- }
- // issue #149: new item before delete
- if (viewBounds.min.y < contentBounds.min.y + m_ContentBottomPadding)
- {
- float size = await NewItemAtEnd(), totalSize = size;
- while (size > 0 && viewBounds.min.y < contentBounds.min.y + m_ContentBottomPadding - totalSize)
- {
- size = await NewItemAtEnd();
- totalSize += size;
- }
- if (totalSize > 0)
- changed = true;
- }
- if (viewBounds.max.y > contentBounds.max.y - m_ContentTopPadding)
- {
- float size = await NewItemAtStart(), totalSize = size;
- while (size > 0 && viewBounds.max.y > contentBounds.max.y - m_ContentTopPadding + totalSize)
- {
- size = await NewItemAtStart();
- totalSize += size;
- }
- if (totalSize > 0)
- changed = true;
- }
- if (viewBounds.min.y > contentBounds.min.y + threshold + m_ContentBottomPadding)
- {
- float size = DeleteItemAtEnd(), totalSize = size;
- while (size > 0 && viewBounds.min.y > contentBounds.min.y + threshold + m_ContentBottomPadding + totalSize)
- {
- size = DeleteItemAtEnd();
- totalSize += size;
- }
- if (totalSize > 0)
- changed = true;
- }
- if (viewBounds.max.y < contentBounds.max.y - threshold - m_ContentTopPadding)
- {
- float size = DeleteItemAtStart(), totalSize = size;
- while (size > 0 && viewBounds.max.y < contentBounds.max.y - threshold - m_ContentTopPadding - totalSize)
- {
- size = DeleteItemAtStart();
- totalSize += size;
- }
- if (totalSize > 0)
- changed = true;
- }
- if (changed)
- {
- ClearTempPool();
- }
- return (changed,viewBounds,contentBounds);
- }
- }
- }
|