Ejemplo n.º 1
0
        /// <summary>
        /// <para>An item width/height can be changed with this method. </para>
        /// <para>Should NOT be called during <see cref="ComputeVisibilityForCurrentPosition(bool, bool, bool)"/>, <see cref="UpdateViewsHolder(TItemViewsHolder)"/>, <see cref="CreateViewsHolder(int)"/> or from any critical view-recycling code. Suggestion: call it from MonBehaviour.Update()</para>
        /// <para>Will change the size of the item's RectTransform to <paramref name="requestedSize"/> and will shift the other items accordingly, if needed.</para>
        /// </summary>
        /// <param name="itemIndex">the index of the item to be resized. It doesn't need to be visible(case in which only the cached size will be updated and, obviously, the visible items will shift accordingly) </param>
        /// <param name="requestedSize">the height or width (depending on scrollview's orientation)</param>
        /// <param name="itemEndEdgeStationary">if to grow to the top/left (less common) instead of down/right (more common)</param>
        /// <returns>the resolved size. This can be slightly different than <paramref name="requestedSize"/> if the number of items is huge (>100k))</returns>
        public float RequestChangeItemSizeAndUpdateLayout(int itemIndex, float requestedSize, bool itemEndEdgeStationary = false, bool computeVisibility = true)
        {
            CancelAnimationsIfAny();

            var skipCompute_oldValue = _SkipComputeVisibilityInUpdateOrOnScroll;

            _SkipComputeVisibilityInUpdateOrOnScroll = true;

            _Params.scrollRect.StopMovement();             // we don't want a ComputeVisibility() during changing an item's size, so we cut off any inertia

            int   itemIndexInView      = _ItemsDesc.GetItemViewIndexFromRealIndex(itemIndex);
            var   viewsHolderIfVisible = GetItemViewsHolderIfVisible(itemIndex);
            float oldSize = _ItemsDesc[itemIndexInView];
            bool  vrtContentPanelIsAtOrBeforeEnd = _InternalState.ContentPanelVirtualInsetFromViewportEnd >= 0d;

            if (requestedSize <= oldSize)             // collapsing
            {
                if (_InternalState.ContentPanelVirtualInsetFromViewportStart >= 0d)
                {
                    itemEndEdgeStationary = false;                     // doesn't make sense to move the start edge if the content pos is at start (or after)
                }
                else if (vrtContentPanelIsAtOrBeforeEnd)
                {
                    itemEndEdgeStationary = true;                     // doesn't make sense to move the end edge if the content pos is at end (or before)
                }
            }

            float resolvedSize =
                _InternalState.ChangeItemSizeAndUpdateContentSizeAccordingly(
                    viewsHolderIfVisible,
                    itemIndexInView,
                    requestedSize,
                    itemEndEdgeStationary
                    );

            float reportedScrollDelta;

            if (itemEndEdgeStationary)
            {
                reportedScrollDelta = .1f;
            }
            else
            {
                // If start edge is stationary, either if the item shrinks or expands the reportedDelta should be negative,
                // indicating that a fake "slight scroll towards end" was done. This triggers a virtualization of the the content's position correctly to compensate for the new ctEnd
                // and makes any item after it be visible again (in the shirnking case) if it was after viewport
                reportedScrollDelta = -.1f;

                // ..but if the ctEnd is fully visible, the items will act as if they're shrinking with itemEndEdgeStationary=true, because the content's end can't exceed the vpEnd
                if (vrtContentPanelIsAtOrBeforeEnd)
                {
                    reportedScrollDelta = .1f;
                }
            }

            if (computeVisibility)
            {
                ComputeVisibilityForCurrentPosition(true, true, false, reportedScrollDelta);
            }
            if (!_CorrectedPositionInCurrentComputeVisibilityPass)
            {
                CorrectPositionsOfVisibleItems(false);                // itemEndEdgeStationary);
            }
            _SkipComputeVisibilityInUpdateOrOnScroll = skipCompute_oldValue;

            return(resolvedSize);
        }
        public float RequestChangeItemSizeAndUpdateLayout(int itemIndex, float requestedSize, bool itemEndEdgeStationary = false, bool computeVisibility = true)
        {
            CancelAnimationsIfAny();

            var skipCompute_oldValue = _SkipComputeVisibilityInUpdateOrOnScroll;

            _SkipComputeVisibilityInUpdateOrOnScroll = true;

            _Collocation.scrollRect.StopMovement();

            int   cellIndex            = _ItemsDesc.GetItemViewIndexFromRealIndex(itemIndex);
            var   viewsHolderIfVisible = GeUILoopSmartItemIfVisible(itemIndex);
            float oldSize = _ItemsDesc[cellIndex];
            bool  vrtContentPanelIsAtOrBeforeEnd = _InternalState.ContentPanelVirtualInsetFromViewportEnd >= 0d;

            if (requestedSize <= oldSize)             // collapsing
            {
                if (_InternalState.ContentPanelVirtualInsetFromViewportStart >= 0d)
                {
                    itemEndEdgeStationary = false;
                }

                else if (vrtContentPanelIsAtOrBeforeEnd)
                {
                    itemEndEdgeStationary = true;
                }
            }

            float resolvedSize =
                _InternalState.ChangeItemSizeAndUpdateContentSizeAccordingly(
                    viewsHolderIfVisible,
                    cellIndex,
                    requestedSize,
                    itemEndEdgeStationary
                    );

            float reportedScrollDelta;

            if (itemEndEdgeStationary)
            {
                reportedScrollDelta = .1f;
            }
            else
            {
                reportedScrollDelta = -.1f;

                if (vrtContentPanelIsAtOrBeforeEnd)
                {
                    reportedScrollDelta = .1f;
                }
            }

            if (computeVisibility)
            {
                ComputeVisibilityForCurrentPosition(true, true, false, reportedScrollDelta);
            }
            if (!_CorrectedPositionInCurrentComputeVisibilityPass)
            {
                CorrectPositionsOfVisibleItems(false);
            }

            _SkipComputeVisibilityInUpdateOrOnScroll = skipCompute_oldValue;

            return(resolvedSize);
        }