Unverified Commit 07fdfb70 authored by jslavitz's avatar jslavitz Committed by GitHub

Fixes switch vibration (#27900)

* Fixes Cupertino switch vibration
parent 29618f0b
...@@ -297,14 +297,6 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { ...@@ -297,14 +297,6 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
markNeedsPaint(); markNeedsPaint();
markNeedsSemanticsUpdate(); markNeedsSemanticsUpdate();
} }
switch(defaultTargetPlatform) {
case TargetPlatform.iOS:
HapticFeedback.lightImpact();
break;
case TargetPlatform.fuchsia:
case TargetPlatform.android:
break;
}
} }
TextDirection get textDirection => _textDirection; TextDirection get textDirection => _textDirection;
...@@ -375,8 +367,10 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { ...@@ -375,8 +367,10 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
} }
void _handleTap() { void _handleTap() {
if (isInteractive) if (isInteractive) {
onChanged(!_value); onChanged(!_value);
_emitVibration();
}
} }
void _handleTapUp(TapUpDetails details) { void _handleTapUp(TapUpDetails details) {
...@@ -390,8 +384,10 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { ...@@ -390,8 +384,10 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
} }
void _handleDragStart(DragStartDetails details) { void _handleDragStart(DragStartDetails details) {
if (isInteractive) if (isInteractive) {
_reactionController.forward(); _reactionController.forward();
_emitVibration();
}
} }
void _handleDragUpdate(DragUpdateDetails details) { void _handleDragUpdate(DragUpdateDetails details) {
...@@ -419,6 +415,17 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { ...@@ -419,6 +415,17 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
_reactionController.reverse(); _reactionController.reverse();
} }
void _emitVibration(){
switch(defaultTargetPlatform) {
case TargetPlatform.iOS:
HapticFeedback.lightImpact();
break;
case TargetPlatform.fuchsia:
case TargetPlatform.android:
break;
}
}
@override @override
bool hitTestSelf(Offset position) => true; bool hitTestSelf(Offset position) => true;
......
...@@ -73,13 +73,177 @@ void main() { ...@@ -73,13 +73,177 @@ void main() {
); );
await tester.tap(find.byKey(switchKey)); await tester.tap(find.byKey(switchKey));
await tester.pumpAndSettle(); await tester.pump();
expect(log, hasLength(1)); expect(log, hasLength(1));
expect(log.single, isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact')); expect(log.single, isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
debugDefaultTargetPlatformOverride = null; debugDefaultTargetPlatformOverride = null;
}); });
testWidgets('Using other widgets that rebuild the switch will not cause vibrations', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
final Key switchKey = UniqueKey();
final Key switchKey2 = UniqueKey();
bool value = false;
bool value2 = false;
final List<MethodCall> log = <MethodCall>[];
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Center(
child: Column(
children: <Widget>[
CupertinoSwitch(
key: switchKey,
value: value,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
),
CupertinoSwitch(
key: switchKey2,
value: value2,
onChanged: (bool newValue) {
setState(() {
value2 = newValue;
});
},
),
]
),
);
},
),
),
);
await tester.tap(find.byKey(switchKey));
await tester.pump();
expect(log, hasLength(1));
expect(log[0], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
await tester.tap(find.byKey(switchKey2));
await tester.pump();
expect(log, hasLength(2));
expect(log[1], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
await tester.tap(find.byKey(switchKey));
await tester.pump();
expect(log, hasLength(3));
expect(log[2], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
await tester.tap(find.byKey(switchKey2));
await tester.pump();
expect(log, hasLength(4));
expect(log[3], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
debugDefaultTargetPlatformOverride = null;
});
testWidgets('Haptic vibration triggers on drag', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
bool value = false;
final List<MethodCall> log = <MethodCall>[];
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Center(
child: CupertinoSwitch(
value: value,
dragStartBehavior: DragStartBehavior.down,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
),
);
},
),
),
);
await tester.drag(find.byType(CupertinoSwitch), const Offset(30.0, 0.0));
expect(value, isTrue);
await tester.pump();
expect(log, hasLength(1));
expect(log[0], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
debugDefaultTargetPlatformOverride = null;
});
testWidgets('No haptic vibration triggers from a programmatic value change', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
final Key switchKey = UniqueKey();
bool value = false;
final List<MethodCall> log = <MethodCall>[];
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Center(
child: Column(
children: <Widget>[
CupertinoButton(
child: const Text('Button'),
onPressed: (){
setState(() {
value = !value;
});
},
),
CupertinoSwitch(
key: switchKey,
value: value,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
),
]
),
);
},
),
),
);
expect(value, isFalse);
await tester.tap(find.byType(CupertinoButton));
expect(value, isTrue);
await tester.pump();
expect(log, hasLength(0));
debugDefaultTargetPlatformOverride = null;
});
testWidgets('Switch can drag (LTR)', (WidgetTester tester) async { testWidgets('Switch can drag (LTR)', (WidgetTester tester) async {
bool value = false; bool value = false;
......
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