Commit 0a8713ef authored by Jason Simmons's avatar Jason Simmons Committed by GitHub

Do not apply scroll offset corrections with zero values during sliver list layout (#10574)

Fixes https://github.com/flutter/flutter/issues/10547
parent 285ab18d
......@@ -485,13 +485,13 @@ class SliverGeometry {
double hitTestExtent,
bool visible,
this.hasVisualOverflow: false,
this.scrollOffsetCorrection: 0.0
this.scrollOffsetCorrection,
}) : assert(scrollExtent != null),
assert(paintExtent != null),
assert(paintOrigin != null),
assert(maxPaintExtent != null),
assert(hasVisualOverflow != null),
assert(scrollOffsetCorrection != null),
assert(scrollOffsetCorrection != 0.0),
layoutExtent = layoutExtent ?? paintExtent,
hitTestExtent = hitTestExtent ?? paintExtent,
visible = visible ?? paintExtent > 0.0;
......@@ -613,7 +613,7 @@ class SliverGeometry {
verify(hitTestExtent >= 0.0, 'The "hitTestExtent" is negative.');
verify(visible != null, 'The "visible" property is null.');
verify(hasVisualOverflow != null, 'The "hasVisualOverflow" is null.');
verify(scrollOffsetCorrection != null, 'The "scrollOffsetCorrection" is null.');
verify(scrollOffsetCorrection != 0.0, 'The "scrollOffsetCorrection" is zero.');
return true;
});
return true;
......@@ -648,7 +648,8 @@ class SliverGeometry {
buffer.write('hitTestExtent: ${hitTestExtent.toStringAsFixed(1)}, ');
if (hasVisualOverflow)
buffer.write('hasVisualOverflow: true, ');
buffer.write('scrollOffsetCorrection: ${scrollOffsetCorrection.toStringAsFixed(1)}');
if (scrollOffsetCorrection != null)
buffer.write('scrollOffsetCorrection: ${scrollOffsetCorrection.toStringAsFixed(1)}');
buffer.write(')');
return buffer.toString();
}
......
......@@ -99,15 +99,23 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor {
earliestUsefulChild = insertAndLayoutLeadingChild(childConstraints, parentUsesSize: true);
if (earliestUsefulChild == null) {
// We ran out of children before reaching the scroll offset.
// We must inform our parent that this sliver cannot fulfill
// its contract and that we need a scroll offset correction.
geometry = new SliverGeometry(
scrollOffsetCorrection: -scrollOffset,
);
final SliverMultiBoxAdaptorParentData childParentData = firstChild.parentData;
childParentData.layoutOffset = 0.0;
return;
if (scrollOffset == 0.0) {
earliestUsefulChild = firstChild;
leadingChildWithLayout = earliestUsefulChild;
trailingChildWithLayout ??= earliestUsefulChild;
break;
} else {
// We ran out of children before reaching the scroll offset.
// We must inform our parent that this sliver cannot fulfill
// its contract and that we need a scroll offset correction.
geometry = new SliverGeometry(
scrollOffsetCorrection: -scrollOffset,
);
return;
}
}
final double firstChildScrollOffset = earliestScrollOffset - paintExtentOf(firstChild);
......
......@@ -260,7 +260,7 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
assert(childLayoutGeometry.debugAssertIsValid);
// If there is a correction to apply, we'll have to start over.
if (childLayoutGeometry.scrollOffsetCorrection != 0.0)
if (childLayoutGeometry.scrollOffsetCorrection != null)
return childLayoutGeometry.scrollOffsetCorrection;
// We use the child's paint origin in our coordinate system as the
......
......@@ -26,7 +26,6 @@ class TestRenderSliverBoxChildManager extends RenderSliverBoxChildManager {
@override
void createChild(int index, { @required RenderBox after }) {
assert(index >= 0);
if (index < 0 || index >= children.length)
return null;
try {
......@@ -213,4 +212,36 @@ void main() {
expect(e.attached, false);
});
test('SliverList - no zero scroll offset correction', () {
RenderSliverList inner;
RenderBox a;
final TestRenderSliverBoxChildManager childManager = new TestRenderSliverBoxChildManager(
children: <RenderBox>[
a = new RenderSizedBox(const Size(100.0, 400.0)),
new RenderSizedBox(const Size(100.0, 400.0)),
new RenderSizedBox(const Size(100.0, 400.0)),
new RenderSizedBox(const Size(100.0, 400.0)),
new RenderSizedBox(const Size(100.0, 400.0)),
],
);
final RenderViewport root = new RenderViewport(
axisDirection: AxisDirection.down,
offset: new ViewportOffset.zero(),
children: <RenderSliver>[
inner = childManager.createRenderObject(),
],
);
layout(root);
final SliverMultiBoxAdaptorParentData parentData = a.parentData;
parentData.layoutOffset = 0.001;
root.offset = new ViewportOffset.fixed(900.0);
pumpFrame();
root.offset = new ViewportOffset.fixed(0.0);
pumpFrame();
expect(inner.geometry.scrollOffsetCorrection, isNull);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment