protected override void performLayout() { this.childManager.didStartLayout(); this.childManager.setDidUnderflow(false); float scrollOffset = this.constraints.scrollOffset + this.constraints.cacheOrigin; D.assert(scrollOffset >= 0.0f); float remainingExtent = this.constraints.remainingCacheExtent; D.assert(remainingExtent >= 0.0f); float targetEndScrollOffset = scrollOffset + remainingExtent; SliverGridLayout layout = this._gridDelegate.getLayout(this.constraints); int firstIndex = layout.getMinChildIndexForScrollOffset(scrollOffset); int?targetLastIndex = targetEndScrollOffset.isFinite() ? (int?)layout.getMaxChildIndexForScrollOffset(targetEndScrollOffset) : null; if (this.firstChild != null) { int oldFirstIndex = this.indexOf(this.firstChild); int oldLastIndex = this.indexOf(this.lastChild); int leadingGarbage = (firstIndex - oldFirstIndex).clamp(0, this.childCount); int trailingGarbage = targetLastIndex == null ? 0 : ((oldLastIndex - targetLastIndex) ?? 0).clamp(0, this.childCount); this.collectGarbage(leadingGarbage, trailingGarbage); } else { this.collectGarbage(0, 0); } SliverGridGeometry firstChildGridGeometry = layout.getGeometryForChildIndex(firstIndex); float?leadingScrollOffset = firstChildGridGeometry.scrollOffset; float?trailingScrollOffset = firstChildGridGeometry.trailingScrollOffset; if (this.firstChild == null) { if (!this.addInitialChild(index: firstIndex, layoutOffset: firstChildGridGeometry.scrollOffset ?? 0.0f)) { float max = layout.computeMaxScrollOffset(this.childManager.childCount ?? 0); this.geometry = new SliverGeometry( scrollExtent: max, maxPaintExtent: max ); this.childManager.didFinishLayout(); return; } } RenderBox trailingChildWithLayout = null; for (int index = this.indexOf(this.firstChild) - 1; index >= firstIndex; --index) { SliverGridGeometry gridGeometry = layout.getGeometryForChildIndex(index); RenderBox child = this.insertAndLayoutLeadingChild( gridGeometry.getBoxConstraints(this.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) { this.firstChild.layout(firstChildGridGeometry.getBoxConstraints(this.constraints)); SliverGridParentData childParentData = this.firstChild.parentData as SliverGridParentData; childParentData.layoutOffset = firstChildGridGeometry.scrollOffset ?? 0.0f; childParentData.crossAxisOffset = firstChildGridGeometry.crossAxisOffset ?? 0.0f; trailingChildWithLayout = this.firstChild; } for (int index = this.indexOf(trailingChildWithLayout) + 1; targetLastIndex == null || index <= targetLastIndex; ++index) { SliverGridGeometry gridGeometry = layout.getGeometryForChildIndex(index); BoxConstraints childConstraints = gridGeometry.getBoxConstraints(this.constraints); RenderBox child = this.childAfter(trailingChildWithLayout); if (child == null) { child = this.insertAndLayoutChild(childConstraints, after: trailingChildWithLayout); if (child == null) { break; } } else { child.layout(childConstraints); } trailingChildWithLayout = child; D.assert(child != null); 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 = this.indexOf(this.lastChild); D.assert(this.childScrollOffset(this.firstChild) <= scrollOffset); D.assert(this.debugAssertChildListIsNonEmptyAndContiguous()); D.assert(this.indexOf(this.firstChild) == firstIndex); D.assert(targetLastIndex == null || lastIndex <= targetLastIndex); float estimatedTotalExtent = this.childManager.estimateMaxScrollOffset(this.constraints, firstIndex: firstIndex, lastIndex: lastIndex, leadingScrollOffset: leadingScrollOffset ?? 0.0f, trailingScrollOffset: trailingScrollOffset ?? 0.0f ); float paintExtent = this.calculatePaintOffset(this.constraints, from: leadingScrollOffset ?? 0.0f, to: trailingScrollOffset ?? 0.0f ); float cacheExtent = this.calculateCacheOffset(this.constraints, from: leadingScrollOffset ?? 0.0f, to: trailingScrollOffset ?? 0.0f ); this.geometry = new SliverGeometry( scrollExtent: estimatedTotalExtent, paintExtent: paintExtent, maxPaintExtent: estimatedTotalExtent, cacheExtent: cacheExtent, hasVisualOverflow: true ); if (estimatedTotalExtent == trailingScrollOffset) { this.childManager.setDidUnderflow(true); } this.childManager.didFinishLayout(); }
public override float childCrossAxisPosition(RenderObject child) { SliverGridParentData childParentData = (SliverGridParentData)child.parentData; return(childParentData.crossAxisOffset); }