mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
avoid forceToPoint in hit-testing when possible (#57519)
This commit is contained in:
parent
b70e7a9b65
commit
ca2abf865e
@ -718,13 +718,12 @@ class _RenderSegmentedControl<T> extends RenderBox
|
||||
while (child != null) {
|
||||
final _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData;
|
||||
if (childParentData.surroundingRect.contains(position)) {
|
||||
final Offset center = (Offset.zero & child.size).center;
|
||||
return result.addWithRawTransform(
|
||||
transform: MatrixUtils.forceToPoint(center),
|
||||
position: center,
|
||||
hitTest: (BoxHitTestResult result, Offset position) {
|
||||
assert(position == center);
|
||||
return child.hitTest(result, position: center);
|
||||
return result.addWithPaintOffset(
|
||||
offset: childParentData.offset,
|
||||
position: position,
|
||||
hitTest: (BoxHitTestResult result, Offset localOffset) {
|
||||
assert(localOffset == position - childParentData.offset);
|
||||
return child.hitTest(result, position: localOffset);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -1025,13 +1025,12 @@ class _RenderSegmentedControl<T> extends RenderBox
|
||||
final _SegmentedControlContainerBoxParentData childParentData =
|
||||
child.parentData as _SegmentedControlContainerBoxParentData;
|
||||
if ((childParentData.offset & child.size).contains(position)) {
|
||||
final Offset center = (Offset.zero & child.size).center;
|
||||
return result.addWithRawTransform(
|
||||
transform: MatrixUtils.forceToPoint(center),
|
||||
position: center,
|
||||
hitTest: (BoxHitTestResult result, Offset position) {
|
||||
assert(position == center);
|
||||
return child.hitTest(result, position: center);
|
||||
return result.addWithPaintOffset(
|
||||
offset: childParentData.offset,
|
||||
position: position,
|
||||
hitTest: (BoxHitTestResult result, Offset localOffset) {
|
||||
assert(localOffset == position - childParentData.offset);
|
||||
return child.hitTest(result, position: localOffset);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -926,6 +926,46 @@ void main() {
|
||||
expect(sharedValue, 0);
|
||||
});
|
||||
|
||||
testWidgets('Hit-tests report accurate local position in segments', (WidgetTester tester) async {
|
||||
final Map<int, Widget> children = <int, Widget>{};
|
||||
TapDownDetails tapDownDetails;
|
||||
children[0] = GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTapDown: (TapDownDetails details) { tapDownDetails = details; },
|
||||
child: const SizedBox(width: 200, height: 200),
|
||||
);
|
||||
children[1] = const Text('Child 2');
|
||||
|
||||
int sharedValue = 1;
|
||||
|
||||
await tester.pumpWidget(
|
||||
StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return boilerplate(
|
||||
child: CupertinoSegmentedControl<int>(
|
||||
key: const ValueKey<String>('Segmented Control'),
|
||||
children: children,
|
||||
onValueChanged: (int newValue) {
|
||||
setState(() {
|
||||
sharedValue = newValue;
|
||||
});
|
||||
},
|
||||
groupValue: sharedValue,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(sharedValue, 1);
|
||||
|
||||
final Offset segment0GlobalOffset = tester.getTopLeft(find.byWidget(children[0]));
|
||||
await tester.tapAt(segment0GlobalOffset + const Offset(7, 11));
|
||||
|
||||
expect(tapDownDetails.localPosition, const Offset(7, 11));
|
||||
expect(tapDownDetails.globalPosition, segment0GlobalOffset + const Offset(7, 11));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Segment still hittable with a child that has no hitbox',
|
||||
(WidgetTester tester) async {
|
||||
|
||||
@ -783,6 +783,38 @@ void main() {
|
||||
expect(groupValue, 1);
|
||||
});
|
||||
|
||||
testWidgets('Hit-tests report accurate local position in segments', (WidgetTester tester) async {
|
||||
final Map<int, Widget> children = <int, Widget>{};
|
||||
TapDownDetails tapDownDetails;
|
||||
children[0] = GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTapDown: (TapDownDetails details) { tapDownDetails = details; },
|
||||
child: const SizedBox(width: 200, height: 200),
|
||||
);
|
||||
children[1] = const Text('Child 2');
|
||||
|
||||
await tester.pumpWidget(
|
||||
boilerplate(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoSlidingSegmentedControl<int>(
|
||||
key: const ValueKey<String>('Segmented Control'),
|
||||
children: children,
|
||||
groupValue: groupValue,
|
||||
onValueChanged: defaultCallback,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(groupValue, 0);
|
||||
|
||||
final Offset segment0GlobalOffset = tester.getTopLeft(find.byWidget(children[0]));
|
||||
await tester.tapAt(segment0GlobalOffset + const Offset(7, 11));
|
||||
|
||||
expect(tapDownDetails.localPosition, const Offset(7, 11));
|
||||
expect(tapDownDetails.globalPosition, segment0GlobalOffset + const Offset(7, 11));
|
||||
});
|
||||
|
||||
testWidgets('Thumb animation is correct when the selected segment changes', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(setupSimpleSegmentedControl());
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user