Use scrollPhysics.allowImplicitScrolling to configure scrollable semantics (#20210)
diff --git a/packages/flutter/lib/src/semantics/semantics.dart b/packages/flutter/lib/src/semantics/semantics.dart
index 4920f23..c23e973 100644
--- a/packages/flutter/lib/src/semantics/semantics.dart
+++ b/packages/flutter/lib/src/semantics/semantics.dart
@@ -3136,6 +3136,18 @@
_setFlag(SemanticsFlag.isObscured, value);
}
+ /// Whether the platform can scroll the semantics node when the user attempts
+ /// to move focus to an offscreen child.
+ ///
+ /// For example, a [ListView] widget has implicit scrolling so that users can
+ /// easily move to the next visible set of children. A [TabBar] widget does
+ /// not have implicit scrolling, so that users can navigate into the tab
+ /// body when reaching the end of the tab bar.
+ bool get hasImplicitScrolling => _hasFlag(SemanticsFlag.hasImplicitScrolling);
+ set hasImplicitScrolling(bool value) {
+ _setFlag(SemanticsFlag.hasImplicitScrolling, value);
+ }
+
/// The currently selected text (or the position of the cursor) within [value]
/// if this node represents a text field.
TextSelection get textSelection => _textSelection;
diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart
index 563ccc0..7193941 100644
--- a/packages/flutter/lib/src/widgets/scrollable.dart
+++ b/packages/flutter/lib/src/widgets/scrollable.dart
@@ -508,6 +508,7 @@
key: _excludableScrollSemanticsKey,
child: result,
position: position,
+ allowImplicitScrolling: widget?.physics?.allowImplicitScrolling ?? false,
);
}
@@ -539,25 +540,39 @@
const _ExcludableScrollSemantics({
Key key,
@required this.position,
+ @required this.allowImplicitScrolling,
Widget child
}) : assert(position != null), super(key: key, child: child);
final ScrollPosition position;
+ final bool allowImplicitScrolling;
@override
- _RenderExcludableScrollSemantics createRenderObject(BuildContext context) => new _RenderExcludableScrollSemantics(position: position);
+ _RenderExcludableScrollSemantics createRenderObject(BuildContext context) {
+ return new _RenderExcludableScrollSemantics(
+ position: position,
+ allowImplicitScrolling: allowImplicitScrolling,
+ );
+ }
+
+
@override
void updateRenderObject(BuildContext context, _RenderExcludableScrollSemantics renderObject) {
- renderObject.position = position;
+ renderObject
+ ..allowImplicitScrolling = allowImplicitScrolling
+ ..position = position;
}
}
class _RenderExcludableScrollSemantics extends RenderProxyBox {
_RenderExcludableScrollSemantics({
@required ScrollPosition position,
+ @required bool allowImplicitScrolling,
RenderBox child,
- }) : _position = position, assert(position != null), super(child) {
+ }) : _position = position,
+ _allowImplicitScrolling = allowImplicitScrolling,
+ assert(position != null), super(child) {
position.addListener(markNeedsSemanticsUpdate);
}
@@ -574,12 +589,23 @@
markNeedsSemanticsUpdate();
}
+ /// Whether this node can be scrolled implicitly.
+ bool get allowImplicitScrolling => _allowImplicitScrolling;
+ bool _allowImplicitScrolling;
+ set allowImplicitScrolling(bool value) {
+ if (value == _allowImplicitScrolling)
+ return;
+ _allowImplicitScrolling = value;
+ markNeedsSemanticsUpdate();
+ }
+
@override
void describeSemanticsConfiguration(SemanticsConfiguration config) {
super.describeSemanticsConfiguration(config);
config.isSemanticBoundary = true;
if (position.haveDimensions) {
config
+ ..hasImplicitScrolling = allowImplicitScrolling
..scrollPosition = _position.pixels
..scrollExtentMax = _position.maxScrollExtent
..scrollExtentMin = _position.minScrollExtent;
diff --git a/packages/flutter/test/widgets/custom_painter_test.dart b/packages/flutter/test/widgets/custom_painter_test.dart
index 4f50cff..444fce5 100644
--- a/packages/flutter/test/widgets/custom_painter_test.dart
+++ b/packages/flutter/test/widgets/custom_painter_test.dart
@@ -428,6 +428,7 @@
flags
..remove(SemanticsFlag.hasImplicitScrolling)
..remove(SemanticsFlag.hasToggledState)
+ ..remove(SemanticsFlag.hasImplicitScrolling)
..remove(SemanticsFlag.isToggled);
TestSemantics expectedSemantics = new TestSemantics.root(
children: <TestSemantics>[
@@ -473,6 +474,7 @@
flags
..remove(SemanticsFlag.hasImplicitScrolling)
..remove(SemanticsFlag.hasCheckedState)
+ ..remove(SemanticsFlag.hasImplicitScrolling)
..remove(SemanticsFlag.isChecked);
expectedSemantics = new TestSemantics.root(
diff --git a/packages/flutter/test/widgets/scrollable_semantics_test.dart b/packages/flutter/test/widgets/scrollable_semantics_test.dart
index bfb3fc3..42840aa 100644
--- a/packages/flutter/test/widgets/scrollable_semantics_test.dart
+++ b/packages/flutter/test/widgets/scrollable_semantics_test.dart
@@ -342,6 +342,9 @@
new TestSemantics.rootChild(
children: <TestSemantics>[
new TestSemantics(
+ flags: <SemanticsFlag>[
+ SemanticsFlag.hasImplicitScrolling,
+ ],
actions: <SemanticsAction>[SemanticsAction.scrollUp],
children: <TestSemantics>[
new TestSemantics(
diff --git a/packages/flutter/test/widgets/semantics_test.dart b/packages/flutter/test/widgets/semantics_test.dart
index 5b1c511..0064558 100644
--- a/packages/flutter/test/widgets/semantics_test.dart
+++ b/packages/flutter/test/widgets/semantics_test.dart
@@ -486,9 +486,9 @@
);
final List<SemanticsFlag> flags = SemanticsFlag.values.values.toList();
flags
- ..remove(SemanticsFlag.hasImplicitScrolling)
..remove(SemanticsFlag.hasToggledState)
- ..remove(SemanticsFlag.isToggled);
+ ..remove(SemanticsFlag.isToggled)
+ ..remove(SemanticsFlag.hasImplicitScrolling);
TestSemantics expectedSemantics = new TestSemantics.root(
children: <TestSemantics>[
diff --git a/packages/flutter/test/widgets/semantics_tester_generateTestSemanticsExpressionForCurrentSemanticsTree_test.dart b/packages/flutter/test/widgets/semantics_tester_generateTestSemanticsExpressionForCurrentSemanticsTree_test.dart
index 0cffd37..db07298 100644
--- a/packages/flutter/test/widgets/semantics_tester_generateTestSemanticsExpressionForCurrentSemanticsTree_test.dart
+++ b/packages/flutter/test/widgets/semantics_tester_generateTestSemanticsExpressionForCurrentSemanticsTree_test.dart
@@ -116,6 +116,7 @@
children: <TestSemantics>[
new TestSemantics(
id: 6,
+ flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
children: <TestSemantics>[
new TestSemantics(
id: 4,
diff --git a/packages/flutter/test/widgets/sliver_semantics_test.dart b/packages/flutter/test/widgets/sliver_semantics_test.dart
index 3671aac..b3f89c5 100644
--- a/packages/flutter/test/widgets/sliver_semantics_test.dart
+++ b/packages/flutter/test/widgets/sliver_semantics_test.dart
@@ -384,6 +384,9 @@
new TestSemantics(
children: <TestSemantics>[
new TestSemantics(
+ flags: <SemanticsFlag>[
+ SemanticsFlag.hasImplicitScrolling,
+ ],
children: <TestSemantics>[
new TestSemantics(
label: 'Item 4',