mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix the issue with SliverMainAxisGroups growing in the reverse direction during layout. (#171005)
Fixes: #170991 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
01f7007a3f
commit
3ed1ca72e1
@ -263,7 +263,14 @@ class RenderSliverMainAxisGroup extends RenderSliver
|
||||
double maxPaintExtent = 0;
|
||||
double paintOffset = constraints.overlap;
|
||||
|
||||
RenderSliver? child = firstChild;
|
||||
final (
|
||||
RenderSliver? leadingChild,
|
||||
RenderSliver? Function(RenderSliver child) advance,
|
||||
) = switch (constraints.growthDirection) {
|
||||
GrowthDirection.forward => (firstChild, childAfter),
|
||||
GrowthDirection.reverse => (lastChild, childBefore),
|
||||
};
|
||||
RenderSliver? child = leadingChild;
|
||||
while (child != null) {
|
||||
final double beforeOffsetPaintExtent = calculatePaintOffset(
|
||||
constraints,
|
||||
@ -298,7 +305,7 @@ class RenderSliverMainAxisGroup extends RenderSliver
|
||||
layoutOffset += childLayoutGeometry.layoutExtent;
|
||||
maxPaintExtent += childLayoutGeometry.maxPaintExtent;
|
||||
paintOffset = math.max(childPaintOffset + childLayoutGeometry.paintExtent, paintOffset);
|
||||
child = childAfter(child);
|
||||
child = advance(child);
|
||||
assert(() {
|
||||
if (child != null && maxPaintExtent.isInfinite) {
|
||||
throw FlutterError(
|
||||
@ -349,11 +356,14 @@ class RenderSliverMainAxisGroup extends RenderSliver
|
||||
|
||||
// Update the children's paintOffset based on the direction again, which
|
||||
// must be done after obtaining the `paintExtent`.
|
||||
child = firstChild;
|
||||
child = leadingChild;
|
||||
while (child != null) {
|
||||
final SliverPhysicalParentData childParentData =
|
||||
child.parentData! as SliverPhysicalParentData;
|
||||
childParentData.paintOffset = switch (constraints.axisDirection) {
|
||||
childParentData.paintOffset = switch (applyGrowthDirectionToAxisDirection(
|
||||
constraints.axisDirection,
|
||||
constraints.growthDirection,
|
||||
)) {
|
||||
AxisDirection.up => Offset(
|
||||
0.0,
|
||||
paintExtent - childParentData.paintOffset.dy - child.geometry!.paintExtent,
|
||||
@ -364,7 +374,7 @@ class RenderSliverMainAxisGroup extends RenderSliver
|
||||
),
|
||||
AxisDirection.right || AxisDirection.down => childParentData.paintOffset,
|
||||
};
|
||||
child = childAfter(child);
|
||||
child = advance(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1062,6 +1062,41 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('SliverMainAxisGroup with center', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
const Key centerKey = Key('center');
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: CustomScrollView(
|
||||
center: centerKey,
|
||||
controller: controller,
|
||||
slivers: const <Widget>[
|
||||
SliverMainAxisGroup(
|
||||
slivers: <Widget>[
|
||||
SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('-2'))),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('-1'))),
|
||||
],
|
||||
),
|
||||
SliverMainAxisGroup(
|
||||
key: centerKey,
|
||||
slivers: <Widget>[
|
||||
SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('1'))),
|
||||
SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('2'))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
controller.jumpTo(-51);
|
||||
await tester.pumpAndSettle();
|
||||
expect(tester.getTopLeft(find.text('-1')), const Offset(0, 1));
|
||||
expect(tester.getTopLeft(find.text('1')), const Offset(0, 51));
|
||||
expect(tester.getTopLeft(find.text('2')), const Offset(0, 101));
|
||||
expect(tester.getTopLeft(find.text('-2')), const Offset(0, -49));
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSliverList({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user