Beispiel #1
0
 protected override bool AdjustmentItemSize(ScrollListItem item)
 {
     if (item.width != itemDefaultfSize.x || item.height != itemDefaultfSize.y)
     {
         item.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, itemDefaultfSize.x);
         item.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, itemDefaultfSize.y);
     }
     return(false);
 }
Beispiel #2
0
 protected override bool AdjustmentItemSize(ScrollListItem item)
 {
     if (item.height != _itemModels[item.index].height)
     {
         //Debug.Log($"item[{item.index}]的尺寸改变 {_itemModels[item.index].height} => {item.height}");
         _itemModels[item.index].height = item.height;
         return(true);
     }
     return(false);
 }
 protected override bool AdjustmentItemSize(ScrollListItem item)
 {
     if (item.width != _itemModels[item.index].width)
     {
         //Debug.Log($"item[{item.index}]的尺寸改变 {_itemModels[item.index].width} => {item.width}");
         _itemModels[item.index].width = item.width;
         return(true);
     }
     return(false);
 }
Beispiel #4
0
        protected override void Refresh(UpdateData updateConfig, out int lastStartIndex)
        {
            if (updateConfig.keepPaddingType == EKeepPaddingType.END)
            {
                var targetRenderStartPos = (ContentHeight - updateConfig.tempLastContentRect.height) + contentRenderStartPos;
                var temp = content.localPosition;
                temp.y = targetRenderStartPos;
                content.localPosition = temp;
            }

            contentRenderStartPos = content.localPosition.y;
            if (contentRenderStartPos < 0)
            {
                contentRenderStartPos = 0;
            }
            else if (contentRenderStartPos > ContentHeight - viewportSize.y)
            {
                contentRenderStartPos = ContentHeight - viewportSize.y;
            }

            int   dataIdx;
            float startPos = layout.paddingTop;

            for (dataIdx = 0; dataIdx < _itemModels.Count; dataIdx++)
            {
                var dataBottom = startPos + _itemModels[dataIdx].height;
                if (dataBottom >= contentRenderStartPos)
                {
                    //就是我了
                    break;
                }

                startPos = dataBottom + layout.gap;
            }

            lastStartIndex = dataIdx;

            //显示的内容刚好大于这个值即可
            float contentHeightLimit = viewportSize.y;
            float itemY = -startPos;

            /// <summary>
            /// 最后一次显示的Item的缓存
            /// </summary>
            Dictionary <ScrollListItemModel, ScrollListItem> lastShowingItems = new Dictionary <ScrollListItemModel, ScrollListItem>(_showingItems);

            _showingItems.Clear();

            while (dataIdx < _itemModels.Count)
            {
                var model = _itemModels[dataIdx];

                ScrollListItem item = CreateItem(model, dataIdx, lastShowingItems);
                //item.gameObject.name += $"_{_itemModels[dataIdx].height}";

                _showingItems[model] = item;

                var pos = Vector3.zero;
                pos.y = itemY;
                item.rectTransform.localPosition = pos;
                //下一个item的Y坐标
                itemY -= (item.height + layout.gap);
                //下一个item的索引
                dataIdx++;

                if (-contentRenderStartPos - itemY >= contentHeightLimit)
                {
                    break;
                }
            }

            //回收没有使用的item
            RecycleUselessItems(lastShowingItems);
        }
Beispiel #5
0
        /// <summary>
        /// 创建一个列表项Item
        /// </summary>
        /// <param name="data"></param>
        /// <param name="dataIdx"></param>
        /// <param name="lastShowingItems"></param>
        /// <returns></returns>
        protected ScrollListItem CreateItem(ScrollListItemModel model, int dataIdx, Dictionary <ScrollListItemModel, ScrollListItem> lastShowingItems)
        {
            ScrollListItem item;

            if (lastShowingItems.ContainsKey(model) && lastShowingItems[model].index == dataIdx) //本来就在显示列表中,直接返回
            {
                item = lastShowingItems[model];
                lastShowingItems.Remove(model);
            }
            else
            {
                if (_recycledItems.Count > 0)
                {
                    ScrollListItem tempItem = null;
                    //tempItem = _recycledItems[0];
                    int idx = _recycledItems.Count;
                    while (--idx > -1)
                    {
                        tempItem = _recycledItems[idx];
                        if (tempItem.index == dataIdx && tempItem.data.Equals(model.data)) //以前回收的一个对象,刚好对应的数据一致,直接返回
                        {
                            item = tempItem;
                            _recycledItems.RemoveAt(idx);
                            item.gameObject.SetActive(true);
                            RenderItem(item, model.data, false);
                            return(item);
                        }
                    }

                    //没有绝对匹配的,则抽取最后找到的item,之后刷新数据并返回
                    item = tempItem;
                    _recycledItems.Remove(tempItem);

                    //当一个列表项,将被复用时触发
                    onItemBeforeReuse?.Invoke(item);
                }
                else
                {
                    var go = GameObject.Instantiate(itemPrefab, content);
                    if (false == go.activeInHierarchy)
                    {
                        go.SetActive(true);
                    }
                    item = go.AddComponent <ScrollListItem>();
                    item.rectTransform.anchorMin = Vector2.up;
                    item.rectTransform.anchorMax = Vector2.up;
                    item.rectTransform.pivot     = Vector2.up;
                    //Debug.Log($"新生成的 Item GameObject");
                }

                var name = string.Format("item_{0}", dataIdx);

                item.gameObject.name = name;
                item.index           = dataIdx;
                item.data            = model.data;
                item.width           = _itemModels[dataIdx].width;
                item.height          = _itemModels[dataIdx].height;

                if (false == item.gameObject.activeInHierarchy)
                {
                    item.gameObject.SetActive(true);
                }

                RenderItem(item, model.data, true);
            }

            if (item.index != dataIdx)
            {
                //插入列表项可能导致数据索引改变
                item.index = dataIdx;
            }

            return(item);
        }
Beispiel #6
0
 /// <summary>
 /// 检测并校正item的大小,如果进行了校正,返回true
 /// </summary>
 /// <param name="item"></param>
 /// <returns></returns>
 protected abstract bool AdjustmentItemSize(ScrollListItem item);
Beispiel #7
0
 protected void RenderItem(ScrollListItem item, object data, bool isOnlySwitchActive)
 {
     onRenderItem?.Invoke(item, data, isOnlySwitchActive);
 }
        protected override void Refresh(UpdateData updateConfig, out int lastStartIndex)
        {
            //内容容器宽度
            var contentWidth = content.rect.width;

            if (updateConfig.keepPaddingType == EKeepPaddingType.END)
            {
                var targetRenderStartPos = (contentWidth - updateConfig.tempLastContentRect.width) + contentRenderStartPos;
                var temp = content.localPosition;
                temp.x = -targetRenderStartPos;
                content.localPosition = temp;
            }

            //content的滚动是负数
            contentRenderStartPos = -content.localPosition.x;


            if (contentRenderStartPos < 0)
            {
                contentRenderStartPos = 0;
            }
            else if (contentRenderStartPos > contentWidth - viewportSize.x)
            {
                contentRenderStartPos = contentWidth - viewportSize.x;
            }

            int   dataIdx;
            float startPos = layout.paddingLeft;

            for (dataIdx = 0; dataIdx < _itemModels.Count; dataIdx++)
            {
                var dataRight = startPos + _itemModels[dataIdx].width;
                if (dataRight >= contentRenderStartPos)
                {
                    //就是我了
                    break;
                }

                startPos = dataRight + layout.gap;
            }
            lastStartIndex = dataIdx;
            //显示的内容刚好大于这个值即可
            float contentWidthLimit = viewportSize.x;
            float itemX             = startPos;

            /// <summary>
            /// 最后一次显示的Item的缓存
            /// </summary>
            Dictionary <ScrollListItemModel, ScrollListItem> lastShowingItems = new Dictionary <ScrollListItemModel, ScrollListItem>(_showingItems);

            _showingItems.Clear();

            while (dataIdx < _itemModels.Count)
            {
                var model = _itemModels[dataIdx];

                ScrollListItem item = CreateItem(model, dataIdx, lastShowingItems);
                //item.gameObject.name += $"_{_itemModels[dataIdx].height}";
                _showingItems[model] = item;

                var pos = Vector3.zero;
                pos.x = itemX;
                item.rectTransform.localPosition = pos;
                //下一个item的X坐标
                itemX += (item.width + layout.gap);
                //下一个item的索引
                dataIdx++;

                if (itemX - contentRenderStartPos >= contentWidthLimit)
                {
                    break;
                }
            }

            //回收没有使用的item
            RecycleUselessItems(lastShowingItems);
        }
Beispiel #9
0
        protected override void Refresh(UpdateData updateConfig, out int lastStartIndex)
        {
            var scrollX = -content.localPosition.x;

            if (scrollX < 0)
            {
                scrollX = 0;
            }
            var scrollY = content.localPosition.y;

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

            bool isColByCol = layout.constraint == EGridConstraint.FIXED_ROW_COUNT ? true : false;

            //计算出关联的所有Item的索引
            List <GridPos> list = new List <GridPos>();

            lastStartIndex = 0;
            if (colCount > 0 && rowCount > 0)
            {
                //根据滚动区域左上角算出起始item的二维位置;
                GridPos startPos = new GridPos((int)(scrollX / _bigW), (int)(scrollY / _bigH), colCount, rowCount, _bigW, _bigH);
                lastStartIndex = startPos.index;
                //根据滚动区域左下角算出结束item的二维位置
                GridPos endPos = new GridPos((int)((scrollX + viewportSize.x) / _bigW), (int)((scrollY + viewportSize.y) / _bigH), colCount, rowCount, _bigW, _bigH);

                if (isColByCol)
                {
                    RefreshGridPosColByCol(list, ref startPos, ref endPos);
                }
                else
                {
                    RefreshGridPosRowByRow(list, ref startPos, ref endPos);
                }
            }

            /// <summary>
            /// 最后一次显示的Item的缓存
            /// </summary>
            Dictionary <ScrollListItemModel, ScrollListItem> lastShowingItems = new Dictionary <ScrollListItemModel, ScrollListItem>(_showingItems);

            _showingItems.Clear();

            for (int i = 0; i < list.Count; i++)
            {
                var gridPos = list[i];
                var model   = _itemModels[gridPos.index];

                ScrollListItem item = CreateItem(model, gridPos.index, lastShowingItems);
                _showingItems[model] = item;
                var pos = new Vector3(gridPos.pixelX, -gridPos.pixelY, 0);
                pos.x += layout.paddingLeft;
                pos.y -= layout.paddingTop;
                item.rectTransform.localPosition = pos;
            }

            //回收没有使用的item
            RecycleUselessItems(lastShowingItems);
        }