public override void Fill(float contentPos)
        {
            float     psDiff        = contentPos + headOffset;
            float     peDiff        = psDiff + currentContentSize - paddedSize;
            float     psEntryOffset = entry[0].info.size;
            float     peEntryOffset = entry[entry.Count - 1].info.size;
            int       totalCount    = indexOffset + currentCount;
            bool      sizeChanged   = false;
            Entry <T> e             = null;

            //Debug.Log($"posOffset {contentPosOffset} psDiff {psDiff} ps {psEntryOffset}");
            if (totalCount == targetCount && contentPos < 0)
            {
                //nothing
            }
            else if (psDiff < 0 && -psDiff >= psEntryOffset + recyclePadding)
            {
                //Debug.Log($"recycle head psDiff {psDiff} ps {psEntryOffset}");
                //recycle head
                indexOffset  += elementPerLine;
                currentCount -= elementPerLine;
                for (int r = 0; r < elementPerLine; ++r)
                {
                    SwitchT(entry[r].item, false);
                }
                entry.RemoveAt(0, elementPerLine);
                headOffset         += psEntryOffset;
                currentContentSize -= psEntryOffset;
            }
            else if (psDiff > 0 && indexOffset > 0)
            {
                //Debug.Log($"add head psDiff {psDiff} ps {psEntryOffset}");
                //add head
                indexOffset  -= elementPerLine;
                currentCount += elementPerLine;
                entry.AddTo(0, elementPerLine);
                for (int r = 0; r < elementPerLine; ++r)
                {
                    e      = ActivateEntry(entry[r]);
                    e.info = FillT(indexOffset + r, e.item);
                    e.transform.anchoredPosition = Repos(r, -e.info.size - currentContentSize);
                    e.transform.name             = (indexOffset + r).ToString();
                }
                headOffset         -= e.info.size;
                currentContentSize += e.info.size;
            }
            if (indexOffset == 0 && contentPos > 0)
            {
                //nothing
            }
            else if (peDiff > 0 && peDiff >= peEntryOffset + recyclePadding)
            {
                //Debug.Log($"recycle tail peDiff {peDiff} pe {peEntryOffset}");
                sizeChanged = true;
                //recycle tail
                for (int r = 0; r < tailCount; ++r)
                {
                    SwitchT((e = entry.RemoveAt(entry.Count - 1)).item, false);
                }
                //Debug.Log($"recycled {tailCount}");
                currentCount       -= tailCount;
                tailCount           = elementPerLine;
                currentContentSize -= peEntryOffset;
            }
            else if (peDiff < 0 && totalCount < targetCount)
            {
                //Debug.Log($"add tail peDiff {peDiff} pe {peEntryOffset}");
                sizeChanged = true;
                //add tail
                tailCount = Mathf.Min(targetCount - totalCount, elementPerLine);
                for (int r = 0; r < tailCount; ++r)
                {
                    e      = ActivateEntry(entry.Add());
                    e.info = FillT(totalCount + r, e.item);
                    e.transform.anchoredPosition = Repos(r, 0);
                    e.transform.name             = (totalCount + r).ToString();
                }
                //Debug.Log($"added {tailCount} {totalCount} {targetCount} {e.offset}");
                currentCount       += tailCount;
                currentContentSize += e.info.size;
            }
            if (sizeChanged)
            {
                RefreshContentSize();
            }
        }