diff --git a/packages/flutter/lib/src/services/haptic_feedback.dart b/packages/flutter/lib/src/services/haptic_feedback.dart index fa41878bd9..067781db8e 100644 --- a/packages/flutter/lib/src/services/haptic_feedback.dart +++ b/packages/flutter/lib/src/services/haptic_feedback.dart @@ -13,14 +13,70 @@ import 'system_channels.dart'; class HapticFeedback { HapticFeedback._(); - /// Provides haptic feedback to the user for a short duration. + /// Provides vibration haptic feedback to the user for a short duration. /// /// On iOS devices that support haptic feedback, this uses the default system /// vibration value (`kSystemSoundID_Vibrate`). /// /// On Android, this uses the platform haptic feedback API to simulate a - /// short tap on a virtual keyboard. + /// response to a long press (`HapticFeedbackConstants.LONG_PRESS`). static Future vibrate() async { await SystemChannels.platform.invokeMethod('HapticFeedback.vibrate'); } + + /// Provides a haptic feedback corresponding a collision impact with a light mass. + /// + /// On iOS versions 10 and above, this uses a `UIImpactFeedbackGenerator` with + /// `UIImpactFeedbackStyleLight`. This call has no effects on iOS versions + /// below 10. + /// + /// On Android, this uses `HapticFeedbackConstants.VIRTUAL_KEY`. + static Future lightImpact() async { + await SystemChannels.platform.invokeMethod( + 'HapticFeedback.vibrate', + 'HapticFeedbackType.lightImpact', + ); + } + + /// Provides a haptic feedback corresponding a collision impact with a medium mass. + /// + /// On iOS versions 10 and above, this uses a `UIImpactFeedbackGenerator` with + /// `UIImpactFeedbackStyleMedium`. This call has no effects on iOS versions + /// below 10. + /// + /// On Android, this uses `HapticFeedbackConstants.KEYBOARD_TAP`. + static Future mediumImpact() async { + await SystemChannels.platform.invokeMethod( + 'HapticFeedback.vibrate', + 'HapticFeedbackType.mediumImpact', + ); + } + + /// Provides a haptic feedback corresponding a collision impact with a heavy mass. + /// + /// On iOS versions 10 and above, this uses a `UIImpactFeedbackGenerator` with + /// `UIImpactFeedbackStyleHeavy`. This call has no effects on iOS versions + /// below 10. + /// + /// On Android, this uses `HapticFeedbackConstants.CONTEXT_CLICK` on API levels + /// 23 and above. This call has no effects on Android API levels below 23. + static Future heavyImpact() async { + await SystemChannels.platform.invokeMethod( + 'HapticFeedback.vibrate', + 'HapticFeedbackType.heavyImpact', + ); + } + + /// Provides a haptic feedback indication selection changing through discrete values. + /// + /// On iOS versions 10 and above, this uses a `UISelectionFeedbackGenerator`. + /// This call has no effects on iOS versions below 10. + /// + /// On Android, this uses `HapticFeedbackConstants.CLOCK_TICK`. + static Future selectionClick() async { + await SystemChannels.platform.invokeMethod( + 'HapticFeedback.vibrate', + 'HapticFeedbackType.selectionClick', + ); + } } diff --git a/packages/flutter/test/services/haptic_feedback_test.dart b/packages/flutter/test/services/haptic_feedback_test.dart index b73a4b05f7..6b08067888 100644 --- a/packages/flutter/test/services/haptic_feedback_test.dart +++ b/packages/flutter/test/services/haptic_feedback_test.dart @@ -18,4 +18,26 @@ void main() { expect(log, hasLength(1)); expect(log.single, isMethodCall('HapticFeedback.vibrate', arguments: null)); }); + + test('Haptic feedback variation tests', () async { + Future callAndVerifyHapticFunction(Function hapticFunction, String platformMethodArgument) async { + final List log = []; + + SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + }); + + await Function.apply(hapticFunction, null); + expect(log, hasLength(1)); + expect( + log.last, + isMethodCall('HapticFeedback.vibrate', arguments: platformMethodArgument), + ); + } + + await callAndVerifyHapticFunction(HapticFeedback.lightImpact, 'HapticFeedbackType.lightImpact'); + await callAndVerifyHapticFunction(HapticFeedback.mediumImpact, 'HapticFeedbackType.mediumImpact'); + await callAndVerifyHapticFunction(HapticFeedback.heavyImpact, 'HapticFeedbackType.heavyImpact'); + await callAndVerifyHapticFunction(HapticFeedback.selectionClick, 'HapticFeedbackType.selectionClick'); + }); }