Ejemplo n.º 1
0
        protected override void performLayout()
        {
            SliverConstraints constraints = this.constraints;

            D.assert(constraints.axisDirection == AxisDirection.down);
            D.assert(constraints.growthDirection == GrowthDirection.forward);
            float layoutExtent =
                (_hasLayoutExtent ? 1.0f : 0.0f) * _refreshIndicatorExtent;

            if (layoutExtent != layoutExtentOffsetCompensation)
            {
                geometry = new SliverGeometry(
                    scrollOffsetCorrection: layoutExtent - layoutExtentOffsetCompensation
                    );
                layoutExtentOffsetCompensation = layoutExtent;
            }
            bool  active             = constraints.overlap <0.0 || layoutExtent> 0.0;
            float overscrolledExtent =
                constraints.overlap < 0.0f ? constraints.overlap.abs() : 0.0f;

            child.layout(
                constraints.asBoxConstraints(
                    maxExtent: layoutExtent + overscrolledExtent
                    ),
                parentUsesSize: true
                );
            if (active)
            {
                geometry = new SliverGeometry(
                    scrollExtent: layoutExtent,
                    paintOrigin: -overscrolledExtent - constraints.scrollOffset,
                    paintExtent: Mathf.Max(
                        Mathf.Max(child.size.height, layoutExtent) - constraints.scrollOffset, 0.0f),
                    maxPaintExtent: Mathf.Max(
                        Mathf.Max(child.size.height, layoutExtent) - constraints.scrollOffset, 0.0f),
                    layoutExtent: Mathf.Max(layoutExtent - constraints.scrollOffset, 0.0f));
            }
            else
            {
                geometry = SliverGeometry.zero;
            }
        }
Ejemplo n.º 2
0
        protected override void performLayout()
        {
            childManager.didStartLayout();
            childManager.setDidUnderflow(false);

            float scrollOffset = constraints.scrollOffset + constraints.cacheOrigin;

            D.assert(scrollOffset >= 0.0f);
            float remainingExtent = constraints.remainingCacheExtent;

            D.assert(remainingExtent >= 0.0f);
            float targetEndScrollOffset = scrollOffset + remainingExtent;

            SliverGridLayout layout = _gridDelegate.getLayout(constraints);

            int firstIndex      = layout.getMinChildIndexForScrollOffset(scrollOffset);
            int?targetLastIndex = targetEndScrollOffset.isFinite()
                ? (int?)layout.getMaxChildIndexForScrollOffset(targetEndScrollOffset)
                : null;

            if (firstChild != null)
            {
                int oldFirstIndex   = indexOf(firstChild);
                int oldLastIndex    = indexOf(lastChild);
                int leadingGarbage  = (firstIndex - oldFirstIndex).clamp(0, childCount);
                int trailingGarbage = targetLastIndex == null
                    ? 0
                    : ((oldLastIndex - targetLastIndex) ?? 0).clamp(0, childCount);
                collectGarbage(leadingGarbage, trailingGarbage);
            }
            else
            {
                collectGarbage(0, 0);
            }

            SliverGridGeometry firstChildGridGeometry = layout.getGeometryForChildIndex(firstIndex);
            float?leadingScrollOffset  = firstChildGridGeometry.scrollOffset;
            float?trailingScrollOffset = firstChildGridGeometry.trailingScrollOffset;

            if (firstChild == null)
            {
                if (!addInitialChild(index: firstIndex,
                                     layoutOffset: firstChildGridGeometry.scrollOffset ?? 0.0f))
                {
                    float max = layout.computeMaxScrollOffset(childManager.childCount ?? 0);
                    geometry = new SliverGeometry(
                        scrollExtent: max,
                        maxPaintExtent: max
                        );
                    childManager.didFinishLayout();
                    return;
                }
            }

            RenderBox trailingChildWithLayout = null;

            for (int index = indexOf(firstChild) - 1; index >= firstIndex; --index)
            {
                SliverGridGeometry gridGeometry = layout.getGeometryForChildIndex(index);
                RenderBox          child        = insertAndLayoutLeadingChild(
                    gridGeometry.getBoxConstraints(constraints)
                    );
                SliverGridParentData childParentData = child.parentData as SliverGridParentData;
                childParentData.layoutOffset    = gridGeometry.scrollOffset ?? 0.0f;
                childParentData.crossAxisOffset = gridGeometry.crossAxisOffset ?? 0.0f;
                D.assert(childParentData.index == index);
                trailingChildWithLayout = trailingChildWithLayout ?? child;
                trailingScrollOffset    =
                    Mathf.Max(trailingScrollOffset ?? 0.0f, gridGeometry.trailingScrollOffset ?? 0.0f);
            }

            if (trailingChildWithLayout == null)
            {
                firstChild.layout(firstChildGridGeometry.getBoxConstraints(constraints));
                SliverGridParentData childParentData = firstChild.parentData as SliverGridParentData;
                childParentData.layoutOffset    = firstChildGridGeometry.scrollOffset ?? 0.0f;
                childParentData.crossAxisOffset = firstChildGridGeometry.crossAxisOffset ?? 0.0f;
                trailingChildWithLayout         = firstChild;
            }

            for (int index = indexOf(trailingChildWithLayout) + 1;
                 targetLastIndex == null || index <= targetLastIndex;
                 ++index)
            {
                SliverGridGeometry gridGeometry     = layout.getGeometryForChildIndex(index);
                BoxConstraints     childConstraints = gridGeometry.getBoxConstraints(constraints);
                RenderBox          child            = childAfter(trailingChildWithLayout);
                if (child == null || indexOf(child) != index)
                {
                    child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout);
                    if (child == null)
                    {
                        break;
                    }
                }
                else
                {
                    child.layout(childConstraints);
                }

                trailingChildWithLayout = child;
                SliverGridParentData childParentData = child.parentData as SliverGridParentData;
                childParentData.layoutOffset    = gridGeometry.scrollOffset ?? 0.0f;
                childParentData.crossAxisOffset = gridGeometry.crossAxisOffset ?? 0.0f;
                D.assert(childParentData.index == index);
                trailingScrollOffset =
                    Mathf.Max(trailingScrollOffset ?? 0.0f, gridGeometry.trailingScrollOffset ?? 0.0f);
            }

            int lastIndex = indexOf(lastChild);

            D.assert(childScrollOffset(firstChild) <= scrollOffset);
            D.assert(debugAssertChildListIsNonEmptyAndContiguous());
            D.assert(indexOf(firstChild) == firstIndex);
            D.assert(targetLastIndex == null || lastIndex <= targetLastIndex);

            float estimatedTotalExtent = childManager.estimateMaxScrollOffset(
                constraints,
                firstIndex: firstIndex,
                lastIndex: lastIndex,
                leadingScrollOffset: leadingScrollOffset ?? 0.0f,
                trailingScrollOffset: trailingScrollOffset ?? 0.0f
                );

            float paintExtent = calculatePaintOffset(
                constraints,
                from: leadingScrollOffset ?? 0.0f,
                to: trailingScrollOffset ?? 0.0f
                );
            float cacheExtent = calculateCacheOffset(
                constraints,
                from: leadingScrollOffset ?? 0.0f,
                to: trailingScrollOffset ?? 0.0f
                );

            geometry = new SliverGeometry(
                scrollExtent: estimatedTotalExtent,
                paintExtent: paintExtent,
                maxPaintExtent: estimatedTotalExtent,
                cacheExtent: cacheExtent,
                hasVisualOverflow: true
                );

            if (estimatedTotalExtent == trailingScrollOffset)
            {
                childManager.setDidUnderflow(true);
            }

            childManager.didFinishLayout();
        }