mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix SliverMainAxisGroup.cacheOrigin (#175760)
Fix #175759 The fix involves using the same logic for cache calculation on RenderViewport. ## 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. - [X] 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.
This commit is contained in:
parent
b5776c5e8d
commit
2e861f3527
@ -296,6 +296,9 @@ class RenderSliverMainAxisGroup extends RenderSliver
|
||||
double paintOffset = constraints.overlap;
|
||||
double maxScrollObstructionExtent = 0;
|
||||
|
||||
double cacheOrigin = constraints.cacheOrigin;
|
||||
double remainingCacheExtent = constraints.remainingCacheExtent;
|
||||
|
||||
final (
|
||||
RenderSliver? leadingChild,
|
||||
RenderSliver? Function(RenderSliver child) advance,
|
||||
@ -310,17 +313,22 @@ class RenderSliverMainAxisGroup extends RenderSliver
|
||||
from: 0.0,
|
||||
to: scrollOffset,
|
||||
);
|
||||
|
||||
final double childScrollOffset = math.max(0.0, constraints.scrollOffset - scrollOffset);
|
||||
final double correctedCacheOrigin = math.max(cacheOrigin, -childScrollOffset);
|
||||
final double cacheExtentCorrection = cacheOrigin - correctedCacheOrigin;
|
||||
|
||||
child.layout(
|
||||
constraints.copyWith(
|
||||
scrollOffset: math.max(0.0, constraints.scrollOffset - scrollOffset),
|
||||
cacheOrigin: math.min(0.0, constraints.cacheOrigin + scrollOffset),
|
||||
scrollOffset: childScrollOffset,
|
||||
cacheOrigin: correctedCacheOrigin,
|
||||
overlap: math.max(0.0, _fixPrecisionError(paintOffset - beforeOffsetPaintExtent)),
|
||||
remainingPaintExtent: _fixPrecisionError(
|
||||
constraints.remainingPaintExtent - beforeOffsetPaintExtent,
|
||||
),
|
||||
remainingCacheExtent: _fixPrecisionError(
|
||||
constraints.remainingCacheExtent -
|
||||
calculateCacheOffset(constraints, from: 0.0, to: scrollOffset),
|
||||
remainingCacheExtent: math.max(
|
||||
0.0,
|
||||
_fixPrecisionError(remainingCacheExtent + cacheExtentCorrection),
|
||||
),
|
||||
precedingScrollExtent: scrollOffset + constraints.precedingScrollExtent,
|
||||
),
|
||||
@ -349,6 +357,12 @@ class RenderSliverMainAxisGroup extends RenderSliver
|
||||
maxPaintExtent += childLayoutGeometry.maxPaintExtent;
|
||||
maxScrollObstructionExtent += childLayoutGeometry.maxScrollObstructionExtent;
|
||||
paintOffset = math.max(childPaintOffset + childLayoutGeometry.paintExtent, paintOffset);
|
||||
if (childLayoutGeometry.cacheExtent != 0.0) {
|
||||
remainingCacheExtent = _fixPrecisionError(
|
||||
remainingCacheExtent - childLayoutGeometry.cacheExtent - cacheExtentCorrection,
|
||||
);
|
||||
cacheOrigin = math.min(correctedCacheOrigin + childLayoutGeometry.cacheExtent, 0.0);
|
||||
}
|
||||
child = advance(child);
|
||||
assert(() {
|
||||
if (child != null && maxPaintExtent.isInfinite) {
|
||||
|
||||
@ -856,6 +856,38 @@ void main() {
|
||||
expect(renderGroup.geometry!.cacheExtent, 850.0);
|
||||
});
|
||||
|
||||
testWidgets('SliverMainAxisGroup has consistent cacheOrigin', (WidgetTester tester) async {
|
||||
const Widget item = SizedBox.square(dimension: 50);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverMainAxisGroup(
|
||||
slivers: <Widget>[
|
||||
const PinnedHeaderSliver(child: SizedBox(height: 500)),
|
||||
SliverList.builder(
|
||||
itemCount: 100,
|
||||
itemBuilder: (BuildContext context, int index) => item,
|
||||
),
|
||||
const SliverToBoxAdapter(child: item),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.scrollUntilVisible(find.byType(SliverToBoxAdapter), 500);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final RenderSliver sliverList =
|
||||
find.byType(SliverList).evaluate().single.findRenderObject()! as RenderSliver;
|
||||
|
||||
expect(sliverList.constraints.cacheOrigin, -250.0);
|
||||
expect(sliverList.constraints.remainingCacheExtent, 1100);
|
||||
});
|
||||
|
||||
testWidgets('SliverMainAxisGroup correctly handles ensureVisible', (WidgetTester tester) async {
|
||||
final GlobalKey key = GlobalKey();
|
||||
await tester.pumpWidget(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user