Unverified Commit 0e9665e4 authored by chunhtai's avatar chunhtai Committed by GitHub

Fixes listview shrinkwrap and hidden semantics node gets updated incorrectly. (#88814)

parent 38186c89
...@@ -5056,7 +5056,6 @@ class RenderIndexedSemantics extends RenderProxyBox { ...@@ -5056,7 +5056,6 @@ class RenderIndexedSemantics extends RenderProxyBox {
@override @override
void describeSemanticsConfiguration(SemanticsConfiguration config) { void describeSemanticsConfiguration(SemanticsConfiguration config) {
super.describeSemanticsConfiguration(config); super.describeSemanticsConfiguration(config);
config.isSemanticBoundary = true;
config.indexInParent = index; config.indexInParent = index;
} }
......
...@@ -1920,6 +1920,14 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta ...@@ -1920,6 +1920,14 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
_maxScrollExtent = 0.0; _maxScrollExtent = 0.0;
_shrinkWrapExtent = 0.0; _shrinkWrapExtent = 0.0;
_hasVisualOverflow = false; _hasVisualOverflow = false;
switch (cacheExtentStyle) {
case CacheExtentStyle.pixel:
_calculatedCacheExtent = cacheExtent;
break;
case CacheExtentStyle.viewport:
_calculatedCacheExtent = mainAxisExtent * _cacheExtent;
break;
}
return layoutChildSequence( return layoutChildSequence(
child: firstChild, child: firstChild,
scrollOffset: math.max(0.0, correctedOffset), scrollOffset: math.max(0.0, correctedOffset),
...@@ -1930,8 +1938,8 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta ...@@ -1930,8 +1938,8 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
crossAxisExtent: crossAxisExtent, crossAxisExtent: crossAxisExtent,
growthDirection: GrowthDirection.forward, growthDirection: GrowthDirection.forward,
advance: childAfter, advance: childAfter,
remainingCacheExtent: mainAxisExtent + 2 * _cacheExtent, remainingCacheExtent: mainAxisExtent + 2 * _calculatedCacheExtent!,
cacheOrigin: -_cacheExtent, cacheOrigin: -_calculatedCacheExtent!,
); );
} }
......
...@@ -310,6 +310,65 @@ void main() { ...@@ -310,6 +310,65 @@ void main() {
expect(find.text('19'), findsOneWidget); expect(find.text('19'), findsOneWidget);
}); });
testWidgets('ListView with shrink wrap in bounded context correctly uses cache extent', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: SizedBox(
height: 400,
child: ListView(
itemExtent: 100.0,
shrinkWrap: true,
children: List<Widget>.generate(20, (int i) {
return Text('Text $i');
}),
),
),
),
);
expect(tester.getSemantics(find.text('Text 5')), matchesSemantics(isHidden: false));
expect(tester.getSemantics(find.text('Text 6', skipOffstage: false)), matchesSemantics(isHidden: true));
expect(tester.getSemantics(find.text('Text 7', skipOffstage: false)), matchesSemantics(isHidden: true));
expect(tester.getSemantics(find.text('Text 8', skipOffstage: false)), matchesSemantics(isHidden: true));
handle.dispose();
});
testWidgets('ListView hidden items should stay hidden if their semantics are updated', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: SizedBox(
height: 400,
child: ListView(
itemExtent: 100.0,
shrinkWrap: true,
children: List<Widget>.generate(20, (int i) {
return Text('Text $i');
}),
),
),
),
);
// Scrollable maybe be marked dirty after layout.
await tester.pumpAndSettle();
expect(tester.getSemantics(find.text('Text 5')), matchesSemantics(isHidden: false));
expect(tester.getSemantics(find.text('Text 6', skipOffstage: false)), matchesSemantics(isHidden: true));
expect(tester.getSemantics(find.text('Text 7', skipOffstage: false)), matchesSemantics(isHidden: true));
expect(tester.getSemantics(find.text('Text 8', skipOffstage: false)), matchesSemantics(isHidden: true));
// Marks Text 6 semantics as dirty.
final RenderObject text6 = tester.renderObject(find.text('Text 6', skipOffstage: false));
text6.markNeedsSemanticsUpdate();
// Verify the semantics is still hidden.
await tester.pump();
expect(tester.getSemantics(find.text('Text 6', skipOffstage: false)), matchesSemantics(isHidden: true));
handle.dispose();
});
testWidgets('didFinishLayout has correct indices', (WidgetTester tester) async { testWidgets('didFinishLayout has correct indices', (WidgetTester tester) async {
final TestSliverChildListDelegate delegate = TestSliverChildListDelegate( final TestSliverChildListDelegate delegate = TestSliverChildListDelegate(
List<Widget>.generate( List<Widget>.generate(
......
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