mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix traversal order issues caused by intersecting or overlapping child rects (#21235)
This commit is contained in:
parent
2f32166f4b
commit
f2442b8a13
@ -2001,14 +2001,16 @@ class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> {
|
||||
List<SemanticsNode> sortedWithinVerticalGroup() {
|
||||
final List<_BoxEdge> edges = <_BoxEdge>[];
|
||||
for (SemanticsNode child in nodes) {
|
||||
// Using a small delta to shrink child rects removes overlapping cases.
|
||||
final Rect childRect = child.rect.deflate(0.1);
|
||||
edges.add(new _BoxEdge(
|
||||
isLeadingEdge: true,
|
||||
offset: _pointInParentCoordinates(child, child.rect.topLeft).dx,
|
||||
offset: _pointInParentCoordinates(child, childRect.topLeft).dx,
|
||||
node: child,
|
||||
));
|
||||
edges.add(new _BoxEdge(
|
||||
isLeadingEdge: false,
|
||||
offset: _pointInParentCoordinates(child, child.rect.bottomRight).dx,
|
||||
offset: _pointInParentCoordinates(child, childRect.bottomRight).dx,
|
||||
node: child,
|
||||
));
|
||||
}
|
||||
@ -2145,14 +2147,16 @@ Offset _pointInParentCoordinates(SemanticsNode node, Offset point) {
|
||||
List<SemanticsNode> _childrenInDefaultOrder(List<SemanticsNode> children, TextDirection textDirection) {
|
||||
final List<_BoxEdge> edges = <_BoxEdge>[];
|
||||
for (SemanticsNode child in children) {
|
||||
// Using a small delta to shrink child rects removes overlapping cases.
|
||||
final Rect childRect = child.rect.deflate(0.1);
|
||||
edges.add(new _BoxEdge(
|
||||
isLeadingEdge: true,
|
||||
offset: _pointInParentCoordinates(child, child.rect.topLeft).dy,
|
||||
offset: _pointInParentCoordinates(child, childRect.topLeft).dy,
|
||||
node: child,
|
||||
));
|
||||
edges.add(new _BoxEdge(
|
||||
isLeadingEdge: false,
|
||||
offset: _pointInParentCoordinates(child, child.rect.bottomRight).dy,
|
||||
offset: _pointInParentCoordinates(child, childRect.bottomRight).dy,
|
||||
node: child,
|
||||
));
|
||||
}
|
||||
|
||||
@ -498,17 +498,6 @@ void main() {
|
||||
label: routeName,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <TestSemantics>[
|
||||
new TestSemantics(
|
||||
id: 8,
|
||||
flags: <SemanticsFlag>[
|
||||
SemanticsFlag.isButton,
|
||||
SemanticsFlag.hasEnabledState,
|
||||
SemanticsFlag.isEnabled,
|
||||
],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Suggestions',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 9,
|
||||
children: <TestSemantics>[
|
||||
@ -541,6 +530,17 @@ void main() {
|
||||
),
|
||||
],
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 8,
|
||||
flags: <SemanticsFlag>[
|
||||
SemanticsFlag.isButton,
|
||||
SemanticsFlag.hasEnabledState,
|
||||
SemanticsFlag.isEnabled,
|
||||
],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Suggestions',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
95
packages/flutter/test/semantics/traversal_order_test.dart
Normal file
95
packages/flutter/test/semantics/traversal_order_test.dart
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Traversal order handles touching elements', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||
await tester.pumpWidget(
|
||||
new MaterialApp(
|
||||
home: new Column(
|
||||
children: new List<Widget>.generate(3, (int column) {
|
||||
return new Row(children: List<Widget>.generate(3, (int row) {
|
||||
return new Semantics(
|
||||
child: new SizedBox(
|
||||
width: 50.0,
|
||||
height: 50.0,
|
||||
child: new Text('$column - $row'),
|
||||
),
|
||||
);
|
||||
}));
|
||||
}),
|
||||
),
|
||||
));
|
||||
|
||||
final TestSemantics expected = new TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
new TestSemantics(
|
||||
id: 1,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <TestSemantics>[
|
||||
new TestSemantics(
|
||||
id: 2,
|
||||
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
||||
children: <TestSemantics>[
|
||||
new TestSemantics(
|
||||
id: 3,
|
||||
label: '0 - 0',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 4,
|
||||
label: '0 - 1',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 5,
|
||||
label: '0 - 2',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 6,
|
||||
label: '1 - 0',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 7,
|
||||
label: '1 - 1',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 8,
|
||||
label: '1 - 2',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 9,
|
||||
label: '2 - 0',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 10,
|
||||
label: '2 - 1',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
new TestSemantics(
|
||||
id: 11,
|
||||
label: '2 - 2',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
expect(semantics, hasSemantics(expected, ignoreRect: true, ignoreTransform: true));
|
||||
semantics.dispose();
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user