123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- using BeinLab.Util;
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
- using XRTool.UI;
- using XRTool.Util;
- namespace XRTool.WorldUI
- {
- /// <summary>
- /// LayoutGroup
- /// </summary>
- public enum LayoutType
- {
- None = -2,
- UnKnow = -1,
- GridLayoutGroup = 0,
- VerticalLayoutGroup = 1,
- HorizontalLayoutGroup = 2,
- }
- /// <summary>
- /// 目标:1实现基本列表功能,生成,销毁,刷新,点击事件的传递等,支持常规的Button,Toggle类型的组件支持
- /// 2,实现滑动循环列表
- /// 3,实现多项内容展示时的优化
- /// 4,指定距离停顿
- /// </summary>
- public class XRScrollRect : ScrollRect
- {
- public bool isLoop;
- public LayoutType layoutType = LayoutType.UnKnow;
- private int allCount;
- private int showCount;
- private Vector2 cellSize;
- private Vector2 cellSpace;
- //private bool isDraging = false;
- private ItemCell superCell;
- private LayoutGroup layoutGroup;
- private List<ItemCell> cellList;
- private Bounds viewBounds;
- //private float dragTime = 0.2f;
- //private float lastDragTime;
- protected override void Start()
- {
- base.Start();
- viewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size);
- }
- public LayoutGroup LayoutGroup
- {
- get
- {
- if (!layoutGroup)
- {
- layoutGroup = content.GetComponent<LayoutGroup>();
- }
- return layoutGroup;
- }
- }
- public List<ItemCell> CellList { get => cellList; set => cellList = value; }
- protected override void LateUpdate()
- {
- if ( velocity.magnitude > 66 || !IsMoveCalculatePosition())
- {
- base.LateUpdate();
- XRUpdateItemVisibility();
- }
- }
- /// <summary>
- /// 更新显示Scroll
- /// </summary>
- private void XRUpdateItemVisibility()
- {
- ///存在子物体,同时显示数据小于总物体数字时
- if (allCount > 0 && showCount < allCount && content.childCount > 0)
- {
- for (int i = 0; i < content.childCount; i++)
- {
- RectTransform child = content.GetChild(i) as RectTransform;
- if (child.anchoredPosition.x < 0)
- {
- child.GetChild(0).gameObject.SetActive(false);
- }
- }
- }
- }
- /// <summary>
- /// 计算最终落点
- /// </summary>
- /// <returns></returns>
- public bool IsMoveCalculatePosition()
- {
- return false;
- }
- /// <summary>
- /// 初始化数据
- /// </summary>
- /// <param name="count"></param>
- /// <param name="showCount"></param>
- /// <param name="cellSize"></param>
- /// <param name="cellSpace"></param>
- /// <param name="prefab"></param>
- public void InitData(int count, int showCount, Vector2 cellSize, Vector3 cellSpace, ItemCell prefab)
- {
- this.allCount = count;
- this.showCount = showCount;
- this.cellSize = cellSize;
- this.cellSpace = cellSpace;
- this.superCell = prefab;
- CreateScrollList();
- }
- public void ClearScrollList()
- {
- if (content)
- {
- for (int i = 0; i < content.childCount; i++)
- {
- Destroy(content.GetChild(i).gameObject);
- }
- }
- CellList.Clear();
- }
- /// <summary>
- /// 创建列表
- /// </summary>
- private void CreateScrollList(bool isClear = true)
- {
- if (CellList == null)
- {
- CellList = new List<ItemCell>();
- }
- if (isClear)
- {
- ClearScrollList();
- }
- GameObject prefab = superCell.GetInstance();
- ///prefab.GetInstance()获取抽象类的实例,不确定这么做可以正常运行,测试中
- if (prefab)
- {
- if (!isLoop)
- {
- int instanceCount = showCount;
- if (showCount >= allCount)
- {
- instanceCount = allCount;
- }
- for (int i = 0; i < instanceCount; i++)
- {
- GameObject obj = Instantiate(prefab);
- UnityUtil.SetParent(content, obj.transform);
- CellList.Add(obj.GetComponent<ItemCell>());
- }
- RectTransform body = GetComponent<RectTransform>();
- Vector2 size = body.sizeDelta;
- if (horizontal && !vertical)
- {
- size.y = cellSize.y;
- //size.x = instanceCount*cellSize.x +
- }
- else if (vertical && !horizontal)
- {
- size.x = cellSize.x;
- }
- }
- }
- if (LayoutGroup)
- {
- if (LayoutGroup is GridLayoutGroup)
- {
- var lay = (LayoutGroup as GridLayoutGroup);
- lay.cellSize = this.cellSize;
- lay.spacing = this.cellSpace;
- }
- else if (LayoutGroup is VerticalLayoutGroup)
- {
- var lay = (LayoutGroup as VerticalLayoutGroup);
- lay.spacing = this.cellSpace.y;
- }
- else if (LayoutGroup is HorizontalLayoutGroup)
- {
- var lay = (LayoutGroup as HorizontalLayoutGroup);
- lay.spacing = this.cellSpace.x;
- }
- }
- }
- //private void XRUpdateScrollbarVisibility()
- //{
- // if (horizontalScrollbar && !isShowHorizontal && horizontalScrollbar.isActiveAndEnabled)
- // {
- // horizontalScrollbar.gameObject.SetActive(false);
- // }
- // if (verticalScrollbar && !isShowVertical && verticalScrollbar.isActiveAndEnabled)
- // {
- // verticalScrollbar.gameObject.SetActive(false);
- // }
- //}
- public override void OnDrag(PointerEventData eventData)
- {
- base.OnDrag(eventData);
- }
- protected override void SetContentAnchoredPosition(Vector2 position)
- {
- base.SetContentAnchoredPosition(position);
- }
- //public override void OnBeginDrag(PointerEventData eventData)
- //{
- // base.OnBeginDrag(eventData);
- // //isDraging = true;
- // //lastDragTime = Time.time;
- //}
- //public override void OnEndDrag(PointerEventData eventData)
- //{
- // base.OnEndDrag(eventData);
- // //isDraging = false;
- // //if (Time.time - lastDragTime < dragTime)
- // //{
- // // if (eventData.pointerEnter)
- // // {
- // // var tmpbutton = eventData.pointerEnter.GetComponentInParent<IPointerClickHandler>();
- // // if (tmpbutton != null)
- // // {
- // // tmpbutton.OnPointerClick(eventData);
- // // }
- // // }
- // //}
- //}
- protected override void OnRectTransformDimensionsChange()
- {
- base.OnRectTransformDimensionsChange();
- viewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size);
- }
- private static float XRRubberDelta(float overStretching, float viewSize)
- {
- return (1 - (1 / ((Mathf.Abs(overStretching) * 0.55f / viewSize) + 1))) * viewSize * Mathf.Sign(overStretching);
- }
- private Vector2 XRCalculateOffset(Vector2 delta)
- {
- return XRInternalCalculateOffset(ref viewBounds, ref m_ContentBounds, horizontal, vertical, movementType, ref delta);
- }
- internal static Vector2 XRInternalCalculateOffset(ref Bounds viewBounds, ref Bounds contentBounds, bool horizontal, bool vertical, MovementType movementType, ref Vector2 delta)
- {
- Vector2 offset = Vector2.zero;
- if (movementType == MovementType.Unrestricted)
- return offset;
- Vector2 min = contentBounds.min;
- Vector2 max = contentBounds.max;
- // min/max offset extracted to check if approximately 0 and avoid recalculating layout every frame (case 1010178)
- if (horizontal)
- {
- min.x += delta.x;
- max.x += delta.x;
- float maxOffset = viewBounds.max.x - max.x;
- float minOffset = viewBounds.min.x - min.x;
- if (minOffset < -0.001f)
- offset.x = minOffset;
- else if (maxOffset > 0.001f)
- offset.x = maxOffset;
- }
- if (vertical)
- {
- min.y += delta.y;
- max.y += delta.y;
- float maxOffset = viewBounds.max.y - max.y;
- float minOffset = viewBounds.min.y - min.y;
- if (maxOffset > 0.001f)
- offset.y = maxOffset;
- else if (minOffset < -0.001f)
- offset.y = minOffset;
- }
- return offset;
- }
- }
- }
|