mirror of
https://github.com/flutter/flutter
synced 2024-08-24 18:36:03 +00:00
Fix SliverMainAxisGroup geometry cacheExtent (#142482)
Fixes https://github.com/flutter/flutter/issues/142183 This fixes a bug in the SliverGeometry of SliverMainAxisGroup. The cacheExtent represents how many pixels the sliver has consumed in the SliverConstraints.remainingCacheExtent. Since it was not set, slivers that came after a SliverMainAxisGroup that filled the whole screen did not properly lay out their own children, in some cases making lazy sliver more eager than they should be.
This commit is contained in:
parent
5bb4fa35f3
commit
e8cb029583
|
@ -284,9 +284,21 @@ class RenderSliverMainAxisGroup extends RenderSliver with ContainerRenderObjectM
|
|||
offset += child.geometry!.scrollExtent;
|
||||
child = childAfter(child);
|
||||
}
|
||||
|
||||
final double paintExtent = calculatePaintOffset(
|
||||
constraints,
|
||||
from: math.min(constraints.scrollOffset, 0),
|
||||
to: totalScrollExtent,
|
||||
);
|
||||
final double cacheExtent = calculateCacheOffset(
|
||||
constraints,
|
||||
from: math.min(constraints.scrollOffset, 0),
|
||||
to: totalScrollExtent,
|
||||
);
|
||||
geometry = SliverGeometry(
|
||||
scrollExtent: totalScrollExtent,
|
||||
paintExtent: calculatePaintOffset(constraints, from: 0, to: totalScrollExtent),
|
||||
paintExtent: paintExtent,
|
||||
cacheExtent: cacheExtent,
|
||||
maxPaintExtent: maxPaintExtent,
|
||||
hasVisualOverflow: totalScrollExtent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0,
|
||||
);
|
||||
|
|
|
@ -692,6 +692,42 @@ void main() {
|
|||
expect(controller.offset, 1000);
|
||||
expect(counter, equals(2));
|
||||
});
|
||||
|
||||
testWidgets('SliverMainAxisGroup does not cause extra builds for lazy sliver children', (WidgetTester tester) async {
|
||||
// By setting the correct SliverGeometry in the first SliverMainAxisGroup,
|
||||
// the following SliverMainAxisGroups will not perform extra work.
|
||||
final Map<int, int> buildsPerGroup = <int, int>{
|
||||
0 : 0,
|
||||
1 : 0,
|
||||
2 : 0,
|
||||
};
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
for (int groupIndex = 0; groupIndex < 3; groupIndex++)
|
||||
SliverMainAxisGroup(
|
||||
slivers: <Widget>[
|
||||
SliverList.builder(
|
||||
itemCount: 100,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
buildsPerGroup[groupIndex] = buildsPerGroup[groupIndex]! + 1;
|
||||
return const SizedBox.square(dimension: 50);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
),
|
||||
));
|
||||
await tester.pumpAndSettle();
|
||||
expect(buildsPerGroup[0], 17); // First sliver filled the screen and cache extent
|
||||
expect(buildsPerGroup[1], 1); // Second only lays out one child
|
||||
expect(buildsPerGroup[2], 1); // Third only lays out one child
|
||||
final RenderSliverMainAxisGroup renderGroup = tester.renderObject(
|
||||
find.byType(SliverMainAxisGroup).first,
|
||||
) as RenderSliverMainAxisGroup;
|
||||
expect(renderGroup.geometry!.cacheExtent, 850.0);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSliverList({
|
||||
|
|
Loading…
Reference in a new issue