コード例 #1
0
        private void GenerateScrollItem(int index, float position, bool topItem)
        {
            int            itemType       = dataSourceInterface.GetItemType(index);
            ScrollItemInfo scrollItemInfo = GetPooledObj(itemType);

            scrollItemInfo.index = index;
            scrollItemInfo.obj   = dataSourceInterface.GetListItem(index, itemType, scrollItemInfo.obj);

            if (scrollItemInfo.obj == null)
            {
                return;
            }

            scrollItemInfo.obj.SetActive(true);
            scrollItemInfo.obj.transform.SetParent(content, false);

            SetupRectTransform(scrollItemInfo.obj.transform as RectTransform);

            visibleObjects.Add(scrollItemInfo);

            if (!CanvasUpdateRegistry.IsRebuildingLayout())
            {
                Canvas.ForceUpdateCanvases();
            }

            PositionScrollItem(scrollItemInfo, position, topItem);

            UpdateScrollItems();
        }
コード例 #2
0
 private void ReturnPooledObj(ScrollItemInfo scrollItemInfo)
 {
     lock (rObjLock) {
         scrollItemInfo.obj.SetActive(false);
         scrollItemInfo.obj.transform.SetParent(pooledObjContainer.transform, false);
         visibleObjects.Remove(scrollItemInfo);
         reuseableObjects.Add(scrollItemInfo);
     }
 }
コード例 #3
0
        private void PositionScrollItem(ScrollItemInfo listItemInfo, float listPos, bool addedItemAtBeginning)
        {
            RectTransform objRectT = listItemInfo.obj.transform as RectTransform;
            float         objSize  = isVertical ? objRectT.rect.height : objRectT.rect.width;

            float spacingOffset = 0;

            if (addedItemAtBeginning)
            {
                spacingOffset = isVertical ? scrollRectContent.spacing : -scrollRectContent.spacing;
            }
            else if (listItemInfo.index != 0)
            {
                spacingOffset = isVertical ? -scrollRectContent.spacing : scrollRectContent.spacing;
            }

            float sizeOffset = (addedItemAtBeginning ? objSize : 0);
            float pos        = isVertical ? listPos + spacingOffset + sizeOffset : listPos + spacingOffset - sizeOffset;

            SetAnchoredPosition(objRectT, pos);

            if (!cachedSizes.ContainsKey(listItemInfo.index) || objSize != cachedSizes[listItemInfo.index])
            {
                float   defaultSize     = scrollInfo.usedSavedSize ? scrollInfo.SavedAvgSize : 0;
                float   sizeDifference  = objSize - (!cachedSizes.ContainsKey(listItemInfo.index) ? defaultSize : cachedSizes[listItemInfo.index]);
                Vector2 contentsNewSize = new Vector2(content.sizeDelta.x, content.sizeDelta.y);
                bool    includeSpacing  = (!cachedSizes.ContainsKey(listItemInfo.index) && listItemInfo.index != itemCount - 1);

                if (isVertical)
                {
                    contentsNewSize.y += sizeDifference + (includeSpacing ? scrollRectContent.spacing : 0);
                }
                else
                {
                    contentsNewSize.x += sizeDifference + (includeSpacing ? scrollRectContent.spacing : 0);
                }

                content.sizeDelta = contentsNewSize;

                if (addedItemAtBeginning)
                {
                    sizeDifference += (!cachedSizes.ContainsKey(listItemInfo.index) && listItemInfo.index != 0) ? scrollRectContent.spacing : 0;
                    sizeDifference *= isVertical ? 1 : -1;
                    ShiftContentBy(sizeDifference);
                }

                scrollInfo.currentTotalSize -= !cachedSizes.ContainsKey(listItemInfo.index) ? 0 : cachedSizes[listItemInfo.index];
                scrollInfo.currentTotalSize += objSize;
                scrollInfo.currentCount     += !cachedSizes.ContainsKey(listItemInfo.index) ? 1 : 0;

                cachedSizes[listItemInfo.index] = objSize;
            }
        }
コード例 #4
0
        private ScrollItemInfo GetPooledObj(int itemType)
        {
            lock (rObjLock) {
                ScrollItemInfo scrollItemInfo = null;

                for (int i = 0; i < reuseableObjects.Count; i++)
                {
                    if (itemType == reuseableObjects[i].itemType)
                    {
                        scrollItemInfo = reuseableObjects[i];
                        reuseableObjects.RemoveAt(i);
                        break;
                    }
                }

                if (scrollItemInfo == null)
                {
                    scrollItemInfo          = new ScrollItemInfo();
                    scrollItemInfo.itemType = itemType;
                }

                return(scrollItemInfo);
            }
        }
コード例 #5
0
        private bool UpdateScrollItems()
        {
            if (itemCount <= 0)
            {
                return(false);
            }

            float topPosValue    = isVertical ? content.anchoredPosition.y : -content.anchoredPosition.x;
            float bottomPosValue = topPosValue + ViewportSize;

            int highestIndex = int.MaxValue;
            int lowestIndex  = int.MinValue;

            float highestVal = float.MinValue;
            float lowestVal  = float.MaxValue;

            for (int i = visibleObjects.Count - 1; i >= 0; i--)
            {
                ScrollItemInfo listItemInfo = visibleObjects[i];
                RectTransform  childRectT   = listItemInfo.obj.transform as RectTransform;

                float val1 = isVertical ? -1 * childRectT.anchoredPosition.y : childRectT.anchoredPosition.x;
                float val2 = isVertical ? childRectT.rect.height : childRectT.rect.width;

                if (val1 < lowestVal)
                {
                    lowestVal   = val1;
                    lowestIndex = listItemInfo.index;
                }
                else if (val1 == lowestVal && lowestIndex > listItemInfo.index)
                {
                    lowestIndex = listItemInfo.index;
                }

                if (val1 + val2 > highestVal)
                {
                    highestVal   = val1 + val2;
                    highestIndex = listItemInfo.index;
                }
                else if (val1 + val2 == highestVal && highestIndex < listItemInfo.index)
                {
                    highestIndex = listItemInfo.index;
                }

                if (val1 + val2 <= topPosValue || val1 >= bottomPosValue)
                {
                    ReturnPooledObj(listItemInfo);
                }
            }

            if (lowestVal >= bottomPosValue)
            {
                float gapSize       = lowestVal - topPosValue;
                int   numItemsInGap = Mathf.CeilToInt(gapSize / scrollInfo.CurrentAvgSize);

                int gotoIndex = lowestIndex - numItemsInGap;

                if (gotoIndex < 0)
                {
                    gotoIndex = 0;
                }

                GoToScrollItem(gotoIndex);

                return(true);
            }

            if (lowestVal - scrollRectContent.spacing > topPosValue && lowestIndex > 0)
            {
                GenerateScrollItem(lowestIndex - 1, isVertical ? -lowestVal : lowestVal, true);

                return(true);
            }

            if (highestVal <= topPosValue)
            {
                float gapSize       = topPosValue - highestVal;
                int   numItemsInGap = Mathf.CeilToInt(gapSize / scrollInfo.CurrentAvgSize);

                int gotoIndex = highestIndex + numItemsInGap;

                if (gotoIndex >= itemCount)
                {
                    gotoIndex = itemCount - 1;
                }

                GoToScrollItem(gotoIndex);

                return(true);
            }

            if (highestVal + scrollRectContent.spacing < bottomPosValue && highestIndex < itemCount - 1)
            {
                GenerateScrollItem(highestIndex + 1, isVertical ? -highestVal : highestVal, false);

                return(true);
            }

            return(false);
        }