Skip to content

Commit fa174b2

Browse files
authored
SingleChildScrollView does not clip semantics child (flutter#114194)
1 parent 0dea659 commit fa174b2

File tree

4 files changed

+141
-188
lines changed

4 files changed

+141
-188
lines changed

packages/flutter/lib/src/widgets/single_child_scroll_view.dart

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,16 +326,13 @@ class _RenderSingleChildViewport extends RenderBox with RenderObjectWithChildMix
326326
_RenderSingleChildViewport({
327327
AxisDirection axisDirection = AxisDirection.down,
328328
required ViewportOffset offset,
329-
double cacheExtent = RenderAbstractViewport.defaultCacheExtent,
330329
RenderBox? child,
331330
required Clip clipBehavior,
332331
}) : assert(axisDirection != null),
333332
assert(offset != null),
334-
assert(cacheExtent != null),
335333
assert(clipBehavior != null),
336334
_axisDirection = axisDirection,
337335
_offset = offset,
338-
_cacheExtent = cacheExtent,
339336
_clipBehavior = clipBehavior {
340337
this.child = child;
341338
}
@@ -370,18 +367,6 @@ class _RenderSingleChildViewport extends RenderBox with RenderObjectWithChildMix
370367
markNeedsLayout();
371368
}
372369

373-
/// {@macro flutter.rendering.RenderViewportBase.cacheExtent}
374-
double get cacheExtent => _cacheExtent;
375-
double _cacheExtent;
376-
set cacheExtent(double value) {
377-
assert(value != null);
378-
if (value == _cacheExtent) {
379-
return;
380-
}
381-
_cacheExtent = value;
382-
markNeedsLayout();
383-
}
384-
385370
/// {@macro flutter.material.Material.clipBehavior}
386371
///
387372
/// Defaults to [Clip.none], and must not be null.
@@ -700,19 +685,34 @@ class _RenderSingleChildViewport extends RenderBox with RenderObjectWithChildMix
700685
@override
701686
Rect describeSemanticsClip(RenderObject child) {
702687
assert(axis != null);
703-
switch (axis) {
704-
case Axis.vertical:
688+
final double remainingOffset = _maxScrollExtent - offset.pixels;
689+
switch (axisDirection) {
690+
case AxisDirection.up:
705691
return Rect.fromLTRB(
706692
semanticBounds.left,
707-
semanticBounds.top - cacheExtent,
693+
semanticBounds.top - remainingOffset,
708694
semanticBounds.right,
709-
semanticBounds.bottom + cacheExtent,
695+
semanticBounds.bottom + offset.pixels,
710696
);
711-
case Axis.horizontal:
697+
case AxisDirection.right:
698+
return Rect.fromLTRB(
699+
semanticBounds.left - offset.pixels,
700+
semanticBounds.top,
701+
semanticBounds.right + remainingOffset,
702+
semanticBounds.bottom,
703+
);
704+
case AxisDirection.down:
705+
return Rect.fromLTRB(
706+
semanticBounds.left,
707+
semanticBounds.top - offset.pixels,
708+
semanticBounds.right,
709+
semanticBounds.bottom + remainingOffset,
710+
);
711+
case AxisDirection.left:
712712
return Rect.fromLTRB(
713-
semanticBounds.left - cacheExtent,
713+
semanticBounds.left - remainingOffset,
714714
semanticBounds.top,
715-
semanticBounds.right + cacheExtent,
715+
semanticBounds.right + offset.pixels,
716716
semanticBounds.bottom,
717717
);
718718
}

packages/flutter/test/material/tabs_test.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2995,14 +2995,15 @@ void main() {
29952995
const String tab0title = 'This is a very wide tab #0\nTab 1 of 20';
29962996
const String tab10title = 'This is a very wide tab #10\nTab 11 of 20';
29972997

2998+
const List<SemanticsFlag> hiddenFlags = <SemanticsFlag>[SemanticsFlag.isHidden, SemanticsFlag.isFocusable];
29982999
expect(semantics, includesNodeWith(actions: <SemanticsAction>[SemanticsAction.scrollLeft]));
29993000
expect(semantics, includesNodeWith(label: tab0title));
3000-
expect(semantics, isNot(includesNodeWith(label: tab10title)));
3001+
expect(semantics, includesNodeWith(label: tab10title, flags: hiddenFlags));
30013002

30023003
controller.index = 10;
30033004
await tester.pumpAndSettle();
30043005

3005-
expect(semantics, isNot(includesNodeWith(label: tab0title)));
3006+
expect(semantics, includesNodeWith(label: tab0title, flags: hiddenFlags));
30063007
expect(semantics, includesNodeWith(actions: <SemanticsAction>[SemanticsAction.scrollLeft, SemanticsAction.scrollRight]));
30073008
expect(semantics, includesNodeWith(label: tab10title));
30083009

@@ -3016,7 +3017,7 @@ void main() {
30163017

30173018
expect(semantics, includesNodeWith(actions: <SemanticsAction>[SemanticsAction.scrollLeft]));
30183019
expect(semantics, includesNodeWith(label: tab0title));
3019-
expect(semantics, isNot(includesNodeWith(label: tab10title)));
3020+
expect(semantics, includesNodeWith(label: tab10title, flags: hiddenFlags));
30203021

30213022
semantics.dispose();
30223023
});

packages/flutter/test/widgets/scrollable_semantics_traversal_order_test.dart

Lines changed: 20 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,25 @@ void main() {
624624
),
625625
);
626626

627+
final List<TestSemantics> children = <TestSemantics>[];
628+
for (int index = 0; index < 30; index += 1) {
629+
final bool isHidden = index < 15 || index > 17;
630+
children.add(
631+
TestSemantics(
632+
flags: isHidden ? <SemanticsFlag>[SemanticsFlag.isHidden] : 0,
633+
label: 'Item ${index}a',
634+
textDirection: TextDirection.ltr,
635+
),
636+
);
637+
children.add(
638+
TestSemantics(
639+
flags: isHidden ? <SemanticsFlag>[SemanticsFlag.isHidden] : 0,
640+
label: 'item ${index}b',
641+
textDirection: TextDirection.ltr,
642+
),
643+
);
644+
}
645+
627646
expect(semantics, hasSemantics(
628647
TestSemantics.root(
629648
children: <TestSemantics>[
@@ -638,72 +657,7 @@ void main() {
638657
SemanticsAction.scrollUp,
639658
SemanticsAction.scrollDown,
640659
],
641-
children: <TestSemantics>[
642-
TestSemantics(
643-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
644-
label: 'Item 13a',
645-
textDirection: TextDirection.ltr,
646-
),
647-
TestSemantics(
648-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
649-
label: 'item 13b',
650-
textDirection: TextDirection.ltr,
651-
),
652-
TestSemantics(
653-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
654-
label: 'Item 14a',
655-
textDirection: TextDirection.ltr,
656-
),
657-
TestSemantics(
658-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
659-
label: 'item 14b',
660-
textDirection: TextDirection.ltr,
661-
),
662-
TestSemantics(
663-
label: 'Item 15a',
664-
textDirection: TextDirection.ltr,
665-
),
666-
TestSemantics(
667-
label: 'item 15b',
668-
textDirection: TextDirection.ltr,
669-
),
670-
TestSemantics(
671-
label: 'Item 16a',
672-
textDirection: TextDirection.ltr,
673-
),
674-
TestSemantics(
675-
label: 'item 16b',
676-
textDirection: TextDirection.ltr,
677-
),
678-
TestSemantics(
679-
label: 'Item 17a',
680-
textDirection: TextDirection.ltr,
681-
),
682-
TestSemantics(
683-
label: 'item 17b',
684-
textDirection: TextDirection.ltr,
685-
),
686-
TestSemantics(
687-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
688-
label: 'Item 18a',
689-
textDirection: TextDirection.ltr,
690-
),
691-
TestSemantics(
692-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
693-
label: 'item 18b',
694-
textDirection: TextDirection.ltr,
695-
),
696-
TestSemantics(
697-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
698-
label: 'Item 19a',
699-
textDirection: TextDirection.ltr,
700-
),
701-
TestSemantics(
702-
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
703-
label: 'item 19b',
704-
textDirection: TextDirection.ltr,
705-
),
706-
],
660+
children: children,
707661
),
708662
],
709663
),

0 commit comments

Comments
 (0)