private ScrollRect _scrollRect;
private ContentSizeFitter _contentSizeFitter;
private VerticalLayoutGroup _verticalLayoutGroup;
private HorizontalLayoutGroup _horizontalLayoutGroup;
private GridLayoutGroup _gridLayoutGroup;
private RectTransform rectTransform;
//private ScrollView scrollView;
private bool _isVertical = false;
private bool _isHorizontal = false;
private float _disableMarginX = 0;
private float _disableMarginY = 0;
private bool _hasDisabledGridComponents = false;
private List<RectTransform> items = new List<RectTransform>();
private Vector2 _newAnchoredPosition = Vector2.zero;
//TO DISABLE FLICKERING OBJECT WHEN SCROLL VIEW IS IDLE IN BETWEEN OBJECTS
//当滚动视图在对象之间空闲时,禁用闪烁对象
private float _treshold = 100;
private int _itemCount = 0;
private float _recordOffsetX = 0;
private float _recordOffsetY = 0;
void Awake()
{
Init();
}
public void Init()
{
if (GetComponent<ScrollRect>() != null)
{
_scrollRect = GetComponent<ScrollRect>();
_scrollRect.onValueChanged.AddListener(OnScroll);
_scrollRect.movementType = ScrollRect.MovementType.Unrestricted;
for (int i = 0; i < _scrollRect.content.childCount; i++)
{
items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
}
if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null)
{
_verticalLayoutGroup = _scrollRect.content.GetComponent<VerticalLayoutGroup>();
}
if (_scrollRect.content.GetComponent<HorizontalLayoutGroup>() != null)
{
_horizontalLayoutGroup = _scrollRect.content.GetComponent<HorizontalLayoutGroup>();
}
if (_scrollRect.content.GetComponent<GridLayoutGroup>() != null)
{
_gridLayoutGroup = _scrollRect.content.GetComponent<GridLayoutGroup>();
}
if (_scrollRect.content.GetComponent<ContentSizeFitter>() != null)
{
_contentSizeFitter = _scrollRect.content.GetComponent<ContentSizeFitter>();
}
_isHorizontal = _scrollRect.horizontal;
_isVertical = _scrollRect.vertical;
if (_isHorizontal && _isVertical)
{
Debug.LogError("UI_InfiniteScroll doesn't support scrolling in both directions, plase choose one direction (horizontal or vertical)");
}
_itemCount = _scrollRect.content.childCount;
}
else
{
Debug.LogError("UI_InfiniteScroll => No ScrollRect component found");
}
}
/// <summary>
/// 禁用网格组件
/// </summary>
void DisableGridComponents()
{
if (_isVertical)
{
//计算item0和item1的锚点y坐标
_recordOffsetY = items[0].GetComponent<RectTransform>().anchoredPosition.y - items[1].GetComponent<RectTransform>().anchoredPosition.y;
//锚点y差值*item的总数/2
_disableMarginY = _recordOffsetY * _itemCount / 2;// _scrollRect.GetComponent<RectTransform>().rect.height/2 + items[0].sizeDelta.y;
}
if (_isHorizontal)
{
_recordOffsetX = items[1].GetComponent<RectTransform>().anchoredPosition.x - items[0].GetComponent<RectTransform>().anchoredPosition.x;
_disableMarginX = _recordOffsetX * _itemCount / 2;//_scrollRect.GetComponent<RectTransform>().rect.width/2 + items[0].sizeDelta.x;
}
if (_verticalLayoutGroup)
{
_verticalLayoutGroup.enabled = false;
}
if (_horizontalLayoutGroup)
{
_horizontalLayoutGroup.enabled = false;
}
if (_contentSizeFitter)
{
_contentSizeFitter.enabled = false;
}
if (_gridLayoutGroup)
{
_gridLayoutGroup.enabled = false;
}
_hasDisabledGridComponents = true;
}
/// <summary>
/// 在滚动的时候
/// </summary>
/// <param name="pos"></param>
public void OnScroll(Vector2 pos)
{
if (!_hasDisabledGridComponents)
DisableGridComponents();
for (int i = 0; i < items.Count; i++)
{
if (_isHorizontal)
{
if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x > _disableMarginX + _treshold)
{
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.x -= _itemCount * _recordOffsetX;
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(_itemCount - 1).transform.SetAsFirstSibling();
}
else if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x < -_disableMarginX)
{
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.x += _itemCount * _recordOffsetX;
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(0).transform.SetAsLastSibling();
}
}
if (_isVertical)
{
//如果物体的y的坐标>锚点y差值*item的总数/2+100时
//当item的y值大于4800+100是时(即当过掉半个content时)
//向下滑 y值减小
if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y > _disableMarginY + _treshold)
{
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.y -= _itemCount * _recordOffsetY;//(9600)
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(_itemCount - 1).transform.SetAsFirstSibling();
Debug.Log("所有锚点差值" + _disableMarginY);
}
//向上滑 y值增加
else if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y < -_disableMarginY)
{
Debug.Log("所有锚点差值" + _disableMarginY);
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.y += _itemCount * _recordOffsetY;
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(0).transform.SetAsLastSibling();
}
}
}
}
效果是引用scrollview组件,自己添加item个数,然后循环出现这几个