flutter_vibration_manager 1.0.0
flutter_vibration_manager: ^1.0.0 copied to clipboard
A production-ready Flutter plugin for advanced vibration, haptic feedback, waveforms, and capability detection on Android and iOS.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_vibration_manager/flutter_vibration_manager.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Vibration Manager',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const VibrationDemoScreen(),
);
}
}
class VibrationDemoScreen extends StatefulWidget {
const VibrationDemoScreen({super.key});
@override
State<VibrationDemoScreen> createState() => _VibrationDemoScreenState();
}
class _VibrationDemoScreenState extends State<VibrationDemoScreen> {
VibrationCapabilities? _capabilities;
bool _isSupported = false;
double _customDuration = 300;
double _customAmplitude = 128;
String _lastStatus = 'Ready';
@override
void initState() {
super.initState();
_loadCapabilities();
}
Future<void> _loadCapabilities() async {
final supported = await FlutterVibrationManager.isSupported();
final caps = await FlutterVibrationManager.capabilities();
if (mounted) {
setState(() {
_isSupported = supported;
_capabilities = caps;
});
}
}
void _showLog(VibrationResult result) {
if (!mounted) return;
setState(() {
_lastStatus = '${result.status.name}${result.message != null ? ': ${result.message}' : ''}';
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Status: ${result.status.name}${result.message != null ? " (${result.message})" : ""}'),
duration: const Duration(seconds: 1),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Vibration Manager Demo'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _loadCapabilities,
tooltip: 'Refresh Capabilities',
)
],
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildCapabilitiesCard(),
const SizedBox(height: 16),
// Basic Vibration Section
_buildSectionHeader('Basic Vibration'),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton.icon(
icon: const Icon(Icons.vibration),
label: const Text('Default (500ms)'),
onPressed: () async {
final res = await FlutterVibrationManager.vibrate();
_showLog(res);
},
),
ElevatedButton(
child: const Text('Short (100ms)'),
onPressed: () async {
final res = await FlutterVibrationManager.vibrate(
duration: const Duration(milliseconds: 100),
);
_showLog(res);
},
),
ElevatedButton(
child: const Text('Long (1000ms)'),
onPressed: () async {
final res = await FlutterVibrationManager.vibrate(
duration: const Duration(milliseconds: 1000),
);
_showLog(res);
},
),
],
),
const SizedBox(height: 16),
// Custom Duration & Amplitude
_buildSectionHeader('Custom Duration & Amplitude'),
Card(
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
children: [
Row(
children: [
Text('Duration: ${_customDuration.toInt()} ms'),
Expanded(
child: Slider(
min: 50,
max: 2000,
divisions: 39,
value: _customDuration,
onChanged: (val) => setState(() => _customDuration = val),
),
),
],
),
Row(
children: [
Text('Amplitude: ${_customAmplitude.toInt()}'),
Expanded(
child: Slider(
min: 1,
max: 255,
divisions: 254,
value: _customAmplitude,
onChanged: (val) => setState(() => _customAmplitude = val),
),
),
],
),
ElevatedButton.icon(
icon: const Icon(Icons.play_arrow),
label: const Text('Play Custom Vibration'),
onPressed: () async {
final res = await FlutterVibrationManager.vibrate(
duration: Duration(milliseconds: _customDuration.toInt()),
amplitude: _customAmplitude.toInt(),
);
_showLog(res);
},
)
],
),
),
),
const SizedBox(height: 16),
// Haptic Feedback
_buildSectionHeader('Haptic Feedback'),
Wrap(
spacing: 8,
runSpacing: 8,
children: HapticType.values.map((type) {
return ActionChip(
label: Text(type.name.toUpperCase()),
onPressed: () async {
final res = await FlutterVibrationManager.haptic(type);
_showLog(res);
},
);
}).toList(),
),
const SizedBox(height: 16),
// Notification Feedback
_buildSectionHeader('Notification Feedback'),
Wrap(
spacing: 8,
runSpacing: 8,
alignment: WrapAlignment.spaceEvenly,
children: [
ElevatedButton.icon(
style: ElevatedButton.styleFrom(backgroundColor: Colors.green.shade100),
icon: const Icon(Icons.check_circle, color: Colors.green),
label: const Text('Success'),
onPressed: () async {
final res = await FlutterVibrationManager.notification(NotificationType.success);
_showLog(res);
},
),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(backgroundColor: Colors.orange.shade100),
icon: const Icon(Icons.warning, color: Colors.orange),
label: const Text('Warning'),
onPressed: () async {
final res = await FlutterVibrationManager.notification(NotificationType.warning);
_showLog(res);
},
),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red.shade100),
icon: const Icon(Icons.error, color: Colors.red),
label: const Text('Error'),
onPressed: () async {
final res = await FlutterVibrationManager.notification(NotificationType.error);
_showLog(res);
},
),
],
),
const SizedBox(height: 16),
// Waveform & Pattern
_buildSectionHeader('Waveforms & Patterns'),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
OutlinedButton.icon(
icon: const Icon(Icons.graphic_eq),
label: const Text('Play Waveform'),
onPressed: () async {
final res = await FlutterVibrationManager.waveform(
pattern: const [
Duration(milliseconds: 0),
Duration(milliseconds: 100),
Duration(milliseconds: 100),
Duration(milliseconds: 200),
Duration(milliseconds: 100),
Duration(milliseconds: 300),
],
amplitudes: const [0, 80, 0, 160, 0, 255],
);
_showLog(res);
},
),
OutlinedButton.icon(
icon: const Icon(Icons.loop),
label: const Text('Start Repeating Pattern'),
onPressed: () async {
final res = await FlutterVibrationManager.waveform(
pattern: const [
Duration(milliseconds: 0),
Duration(milliseconds: 200),
Duration(milliseconds: 300),
],
repeat: 0,
);
_showLog(res);
},
),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
),
icon: const Icon(Icons.stop),
label: const Text('Cancel Vibration'),
onPressed: () async {
final res = await FlutterVibrationManager.cancel();
_showLog(res);
},
),
],
),
const SizedBox(height: 16),
// Status Footer
Card(
color: Colors.grey.shade100,
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
'Last Operation Status: $_lastStatus',
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
),
],
),
);
}
Widget _buildSectionHeader(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
color: Colors.deepPurple,
),
),
);
}
Widget _buildCapabilitiesCard() {
return Card(
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Device Capabilities',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const Divider(),
_buildCapabilityRow('Platform Supported', _isSupported),
_buildCapabilityRow('Has Vibrator', _capabilities?.hasVibrator ?? false),
_buildCapabilityRow('Supports Amplitude', _capabilities?.supportsAmplitude ?? false),
_buildCapabilityRow('Supports Haptics', _capabilities?.supportsHaptics ?? false),
_buildCapabilityRow('Supports Waveform', _capabilities?.supportsWaveform ?? false),
],
),
),
);
}
Widget _buildCapabilityRow(String label, bool value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label),
Icon(
value ? Icons.check_circle : Icons.cancel,
color: value ? Colors.green : Colors.red,
size: 20,
),
],
),
);
}
}