### Complete Widget Integration Example Source: https://context7.com/nohli/haptic_feedback/llms.txt Full Flutter widget that checks capability before vibrating and handles all haptic types with Android-specific controls. Includes dropdown for usage category and a switch for Android haptic constants. ```dart import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:haptic_feedback/haptic_feedback.dart'; class HapticDemoPage extends StatefulWidget { const HapticDemoPage({super.key}); @override State createState() => _HapticDemoPageState(); } class _HapticDemoPageState extends State { HapticsUsage? _usage; bool _useConstants = false; Future _trigger(HapticsType type) async { final bool can = await Haptics.canVibrate(); if (!can) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Haptics not supported on this device')), ); return; } try { await Haptics.vibrate( type, usage: _usage, useAndroidHapticConstants: _useConstants, ); } on PlatformException catch (e) { debugPrint('Haptic error [${e.code}]: ${e.message}'); } } @override Widget build(BuildContext context) { final isAndroid = !kIsWeb && defaultTargetPlatform == TargetPlatform.android; return Scaffold( appBar: AppBar(title: const Text('Haptic Feedback Demo')), body: Column( children: [ if (isAndroid) ...[ DropdownButton( hint: const Text('Usage category'), value: _usage, items: HapticsUsage.values .map((u) => DropdownMenuItem(value: u, child: Text(u.name))) .toList(), onChanged: (v) => setState(() => _usage = v), ), SwitchListTile( title: const Text('Use Android HapticFeedbackConstants'), value: _useConstants, onChanged: (v) => setState(() => _useConstants = v), ), ], Expanded( child: ListView( children: HapticsType.values .map((type) => ListTile( title: Text(type.name), onTap: () => _trigger(type), )) .toList(), ), ), ], ), ); } } ``` -------------------------------- ### HapticsType Enum Usage Source: https://context7.com/nohli/haptic_feedback/llms.txt Utilize the `HapticsType` enum for semantic haptic patterns. Examples show typical usage in form submissions, slider interactions, and button presses. ```dart import 'package:haptic_feedback/haptic_feedback.dart'; // All available values const types = HapticsType.values; // [success, warning, error, light, medium, heavy, rigid, soft, selection] // Typical semantic usage in a form submission flow Future onFormSubmit({required bool isSuccess}) async { await Haptics.vibrate( isSuccess ? HapticsType.success : HapticsType.error, ); } // Slider / picker interaction Future onSliderChange() async { await Haptics.vibrate(HapticsType.selection); } // Button press with impact weight based on action destructiveness Future onDeleteButtonTap() async { await Haptics.vibrate(HapticsType.heavy); // high-stakes action } Future onCardTap() async { await Haptics.vibrate(HapticsType.light); // lightweight interaction } ``` -------------------------------- ### Enable Swift Package Manager via CLI Source: https://context7.com/nohli/haptic_feedback/llms.txt Use the Flutter CLI to enable Swift Package Manager for iOS builds. Remember to clean the project after switching. ```shell # Or via CLI flutter config --enable-swift-package-manager # Revert to CocoaPods flutter config --no-enable-swift-package-manager # After switching, clean build artefacts to avoid Xcode cache issues flutter clean rm -rf ~/Library/Developer/Xcode/DerivedData/Runner-* ``` -------------------------------- ### Mock Haptic Feedback Platform Instance Source: https://context7.com/nohli/haptic_feedback/llms.txt Replace the platform instance with a mock to avoid MissingPluginException during tests. This mock implementation always returns true for canVibrate and does nothing for vibrate. ```dart import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:haptic_feedback/haptic_feedback.dart'; import 'package:haptic_feedback/src/haptic_feedback_platform_interface.dart'; import 'package:haptic_feedback/src/haptic_feedback_method_channel.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; // --- Strategy 1: Replace the platform instance with a mock --- class MockHapticFeedbackPlatform extends HapticFeedbackPlatform with MockPlatformInterfaceMixin { @override Future canVibrate() async => true; @override Future vibrate( HapticsType type, { HapticsUsage? usage, bool useAndroidHapticConstants = false, }) async {} } void main() { final initialPlatform = HapticFeedbackPlatform.instance; tearDown(() => HapticFeedbackPlatform.instance = initialPlatform); test('mock platform interface', () async { HapticFeedbackPlatform.instance = MockHapticFeedbackPlatform(); expect(await Haptics.canVibrate(), isTrue); await Haptics.vibrate( HapticsType.success, usage: HapticsUsage.notification, useAndroidHapticConstants: true, ); // No MissingPluginException thrown }); // --- Strategy 2: Mock the method channel directly --- test('mock method channel', () async { TestWidgetsFlutterBinding.ensureInitialized(); const channel = MethodChannelHapticFeedback.methodChannel; MethodCall? lastCall; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall call) async { lastCall = call; if (call.method == 'canVibrate') return true; return null; }); addTearDown(() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, null); }); final platform = MethodChannelHapticFeedback(); expect(await platform.canVibrate(), isTrue); await platform.vibrate( HapticsType.success, usage: HapticsUsage.media, useAndroidHapticConstants: true, ); // Verify the channel received the correct method name and arguments expect(lastCall?.method, 'success'); expect(lastCall?.arguments, { 'usage': 'media', 'useAndroidHapticConstants': true, }); }); // --- Strategy 3: Override target platform --- testWidgets('platform guard on iOS', (tester) async { debugDefaultTargetPlatformOverride = TargetPlatform.iOS; addTearDown(() => debugDefaultTargetPlatformOverride = null); HapticFeedbackPlatform.instance = MockHapticFeedbackPlatform(); expect(await Haptics.canVibrate(), isTrue); }); } ``` -------------------------------- ### Add haptic_feedback Dependency Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Add the haptic_feedback package to your Flutter project using the flutter pub add command. ```shell flutter pub add haptic_feedback ``` -------------------------------- ### Mock Haptic Feedback Platform Interface Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Mock the `HapticFeedbackPlatform` interface to control its behavior during tests. This is useful for verifying interactions with the haptic feedback system. ```dart import 'package:haptic_feedback/src/haptic_feedback_platform_interface.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; class MockHapticFeedbackPlatform extends Mock with MockPlatformInterfaceMixin implements HapticFeedbackPlatform {} void main() { testWidgets('my widget test', (tester) async { final mockPlatform = MockHapticFeedbackPlatform(); HapticFeedbackPlatform.instance = mockPlatform; when(() => mockPlatform.canVibrate()).thenAnswer((_) async => true); when(() => mockPlatform.vibrate(any())).thenAnswer((_) async {}); // Your test code here }); } ``` -------------------------------- ### Use Android Haptic Constants Source: https://context7.com/nohli/haptic_feedback/llms.txt Opt-in to use Android's system HapticFeedbackConstants instead of custom primitives. This flag is effective on API level 30+ for CONFIRM/REJECT and API level 5+ for VIRTUAL_KEY. Note that 'warning', 'rigid', and 'soft' types do not have direct Android constant mappings and will always use primitives. ```dart import 'package:haptic_feedback/haptic_feedback.dart'; // Default: iOS-aligned primitives (VibrationEffect.Composition) await Haptics.vibrate(HapticsType.success); // Opt-in to system HapticFeedbackConstants await Haptics.vibrate( HapticsType.success, useAndroidHapticConstants: true, // uses HapticFeedbackConstants.CONFIRM (API ≥ 30) ); await Haptics.vibrate( HapticsType.error, useAndroidHapticConstants: true, // uses HapticFeedbackConstants.REJECT (API ≥ 30) ); await Haptics.vibrate( HapticsType.light, useAndroidHapticConstants: true, // uses HapticFeedbackConstants.VIRTUAL_KEY (API ≥ 5) ); ``` -------------------------------- ### Android Haptic Feedback Options Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Configure Android-specific haptic feedback behavior. Use native Android haptic constants or specify vibration usage hints for Android 13+. ```dart // Use native Android haptic constants (default: false) // When true, uses HapticFeedbackConstants like CONFIRM, REJECT, etc. // When false, uses custom vibration primitives that are more aligned // with iOS haptics await Haptics.vibrate( HapticsType.success, useAndroidHapticConstants: false, // default ); // On Android 13+, you can hint how the system should treat this vibration // (alarm, communicationRequest, hardwareFeedback, media, notification, physicalEmulation, ringtone, touch, unknown) await Haptics.vibrate( HapticsType.success, usage: HapticsUsage.media, ); ``` -------------------------------- ### Handle Platform Exceptions for Haptics Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Wrap haptic feedback calls in a try/catch block to gracefully handle potential PlatformExceptions, such as VIBRATION_ERROR, preventing app crashes. ```dart try { await Haptics.vibrate(HapticsType.success); } on PlatformException catch (e) { // Handle or log as needed } ``` -------------------------------- ### Mock Method Channel for Haptic Feedback Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Mock the method channel to prevent `MissingPluginException` when testing the real platform class. This allows testing channel communication directly. ```dart import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:haptic_feedback/src/haptic_feedback_method_channel.dart'; import 'package:haptic_feedback/src/haptics_type.dart'; void main() { const channel = MethodChannelHapticFeedback.methodChannel; TestDefaultBinaryMessengerBinding.ensureInitialized(); setUp(() { final binding = TestDefaultBinaryMessengerBinding.instance; binding.defaultBinaryMessenger.setMockMethodCallHandler( channel, (MethodCall call) async { if (call.method == 'canVibrate') return true; return null; // success for vibrate calls }, ); }); tearDown(() { final binding = TestDefaultBinaryMessengerBinding.instance; binding.defaultBinaryMessenger.setMockMethodCallHandler(channel, null); }); test('canVibrate works with mocked channel', () async { expect(await MethodChannelHapticFeedback().canVibrate(), isTrue); }); test('vibrate forwards to mocked channel', () async { await MethodChannelHapticFeedback().vibrate(HapticsType.success); }); } ``` -------------------------------- ### Haptics.vibrate(HapticsType type) Source: https://context7.com/nohli/haptic_feedback/llms.txt Triggers a haptic pattern matching the given HapticsType. It performs nothing on unsupported platforms and catches native exceptions, surfacing them as a PlatformException. ```APIDOC ## Haptics.vibrate(HapticsType type) ### Description Triggers a haptic pattern matching the given `HapticsType`. Performs nothing on unsupported platforms. Native exceptions are caught and surfaced as a `PlatformException` with code `VIBRATION_ERROR`; wrapping calls in a try/catch is recommended for defensive production code. ### Method `Future vibrate(HapticsType type)` ### Parameters #### Path Parameters - **type** (`HapticsType`) - Required - The type of haptic feedback to trigger. ### Usage Example ```dart import 'package:haptic_feedback/haptic_feedback.dart'; import 'package:flutter/services.dart'; Future triggerFeedback() async { // Notification feedback: task completed, caution, or failure await Haptics.vibrate(HapticsType.success); await Haptics.vibrate(HapticsType.warning); await Haptics.vibrate(HapticsType.error); // Impact feedback: collision weight await Haptics.vibrate(HapticsType.light); await Haptics.vibrate(HapticsType.medium); await Haptics.vibrate(HapticsType.heavy); // Impact feedback: surface hardness await Haptics.vibrate(HapticsType.rigid); await Haptics.vibrate(HapticsType.soft); // Selection feedback: value changing await Haptics.vibrate(HapticsType.selection); } // Defensive usage with error handling Future safeVibrate() async { try { await Haptics.vibrate(HapticsType.success); } on PlatformException catch (e) { // e.code == 'VIBRATION_ERROR' print('Haptic error: ${e.message}'); } } ``` ``` -------------------------------- ### Basic Haptic Feedback Usage Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Check if vibration is supported and trigger various haptic feedback types like success, warning, error, light, medium, heavy, rigid, soft, and selection. ```dart final canVibrate = await Haptics.canVibrate(); await Haptics.vibrate(HapticsType.success); await Haptics.vibrate(HapticsType.warning); await Haptics.vibrate(HapticsType.error); await Haptics.vibrate(HapticsType.light); await Haptics.vibrate(HapticsType.medium); await Haptics.vibrate(HapticsType.heavy); await Haptics.vibrate(HapticsType.rigid); await Haptics.vibrate(HapticsType.soft); await Haptics.vibrate(HapticsType.selection); ``` -------------------------------- ### HapticsType enum Source: https://context7.com/nohli/haptic_feedback/llms.txt Defines the nine semantic haptic patterns available across both platforms, mirroring Apple's iOS Human Interface Guidelines. ```APIDOC ## HapticsType enum ### Description Defines the nine semantic haptic patterns available across both platforms, mirroring Apple's iOS Human Interface Guidelines. ### Values - `success` - `warning` - `error` - `light` - `medium` - `heavy` - `rigid` - `soft` - `selection` ### Usage Example ```dart import 'package:haptic_feedback/haptic_feedback.dart'; // All available values const types = HapticsType.values; // [success, warning, error, light, medium, heavy, rigid, soft, selection] // Typical semantic usage in a form submission flow Future onFormSubmit({required bool isSuccess}) async { await Haptics.vibrate( isSuccess ? HapticsType.success : HapticsType.error, ); } // Slider / picker interaction Future onSliderChange() async { await Haptics.vibrate(HapticsType.selection); } // Button press with impact weight based on action destructiveness Future onDeleteButtonTap() async { await Haptics.vibrate(HapticsType.heavy); // high-stakes action } Future onCardTap() async { await Haptics.vibrate(HapticsType.light); // lightweight interaction } ``` ``` -------------------------------- ### Enable Swift Package Manager in Flutter Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Configure your Flutter project to use Swift Package Manager (SPM) for iOS dependencies, or disable it if encountering issues. ```yaml flutter: config: enable-swift-package-manager: true ``` ```yaml flutter: config: enable-swift-package-manager: false ``` -------------------------------- ### Enable Swift Package Manager in pubspec.yaml Source: https://context7.com/nohli/haptic_feedback/llms.txt Configure your Flutter project to use Swift Package Manager for iOS by setting `enable-swift-package-manager` to true in `pubspec.yaml`. ```yaml # pubspec.yaml — enable Swift Package Manager (Flutter 3.24+) flutter: config: enable-swift-package-manager: true ``` -------------------------------- ### Haptics.canVibrate() Source: https://context7.com/nohli/haptic_feedback/llms.txt Checks if the current device supports haptic feedback. Returns true for iPhone 7 and later on iOS, and varies by device/OS on Android. Always returns false on web and desktop. ```APIDOC ## Haptics.canVibrate() ### Description Returns `true` when the current device supports haptic feedback. On iOS this is `true` for iPhone 7 and later; on Android it varies by device and OS version. Always returns `false` on web and desktop platforms — no exception is thrown. ### Method `Future canVibrate()` ### Usage Example ```dart import 'package:haptic_feedback/haptic_feedback.dart'; Future checkCapability() async { final bool canVibrate = await Haptics.canVibrate(); if (canVibrate) { print('Device supports haptic feedback'); } else { print('Haptic feedback not available on this device'); } } ``` ``` -------------------------------- ### Override Default Target Platform for Testing Source: https://github.com/nohli/haptic_feedback/blob/main/README.md Use `debugDefaultTargetPlatformOverride` to simulate specific platform behavior during tests. Remember to reset it using `addTearDown`. ```dart import 'package:flutter/foundation.dart'; void main() { testWidgets('test on iOS', (tester) async { debugDefaultTargetPlatformOverride = TargetPlatform.iOS; addTearDown(() => debugDefaultTargetPlatformOverride = null); // Your test code here }); } ``` -------------------------------- ### Trigger Haptic Feedback Source: https://context7.com/nohli/haptic_feedback/llms.txt Trigger haptic patterns using `Haptics.vibrate()` with `HapticsType`. Catches `PlatformException` for `VIBRATION_ERROR` for defensive programming. ```dart import 'package:haptic_feedback/haptic_feedback.dart'; import 'package:flutter/services.dart'; Future triggerFeedback() async { // Notification feedback: task completed, caution, or failure await Haptics.vibrate(HapticsType.success); await Haptics.vibrate(HapticsType.warning); await Haptics.vibrate(HapticsType.error); // Impact feedback: collision weight await Haptics.vibrate(HapticsType.light); await Haptics.vibrate(HapticsType.medium); await Haptics.vibrate(HapticsType.heavy); // Impact feedback: surface hardness await Haptics.vibrate(HapticsType.rigid); await Haptics.vibrate(HapticsType.soft); // Selection feedback: value changing await Haptics.vibrate(HapticsType.selection); } // Defensive usage with error handling Future safeVibrate() async { try { await Haptics.vibrate(HapticsType.success); } on PlatformException catch (e) { // e.code == 'VIBRATION_ERROR' print('Haptic error: ${e.message}'); } } ``` -------------------------------- ### Check Haptic Feedback Capability Source: https://context7.com/nohli/haptic_feedback/llms.txt Use `Haptics.canVibrate()` to determine if the device supports haptic feedback. This method returns `false` on web and desktop platforms without throwing an exception. ```dart import 'package:haptic_feedback/haptic_feedback.dart'; Future checkCapability() async { final bool canVibrate = await Haptics.canVibrate(); if (canVibrate) { print('Device supports haptic feedback'); } else { print('Haptic feedback not available on this device'); } } ``` -------------------------------- ### Control Android Haptics Usage Source: https://context7.com/nohli/haptic_feedback/llms.txt Control the VibrationAttributes usage category on Android 13+ (API 33+) to manage how the system routes and volumes vibrations. This setting is ignored on older Android versions and iOS. Defaults to HapticsUsage.unknown. Some OEM builds may mute vibrations if touch haptics are disabled. ```dart import 'package:haptic_feedback/haptic_feedback.dart'; // Notification / alarm contexts await Haptics.vibrate( HapticsType.warning, usage: HapticsUsage.notification, // respects notification vibration settings ); await Haptics.vibrate( HapticsType.error, usage: HapticsUsage.alarm, // respects alarm volume settings ); // Media / immersive contexts (e.g., games, breathing exercises) await Haptics.vibrate( HapticsType.heavy, usage: HapticsUsage.media, ); // Ringtone await Haptics.vibrate( HapticsType.success, usage: HapticsUsage.ringtone, ); // Combining with useAndroidHapticConstants await Haptics.vibrate( HapticsType.success, usage: HapticsUsage.touch, useAndroidHapticConstants: true, ); // All HapticsUsage values: // alarm, communicationRequest, hardwareFeedback, media, // notification, physicalEmulation, ringtone, touch, unknown ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.