update flutter_vibrate
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "flutter_vibrate",
|
"name": "flutter_vibrate",
|
||||||
"version": "1.3.0",
|
"version": "1.4.0",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"flutter"
|
"flutter"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
## 1.4.0
|
||||||
|
|
||||||
|
* Migrated to Pigeon for type-safe platform channels.
|
||||||
|
* Fixed Android permission issue (restored `VIBRATE` permission).
|
||||||
|
* Refactored Android implementation to use `View.performHapticFeedback` for compatible feedback.
|
||||||
|
* Modernized example app with Material 3 and better UI.
|
||||||
|
|
||||||
## 1.3.0
|
## 1.3.0
|
||||||
|
|
||||||
* Fixing swift version
|
* Fixing swift version
|
||||||
|
|||||||
@@ -1,21 +1,202 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2018 Clovis NICOLAS
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
1. Definitions.
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
the copyright owner that is granting the License.
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
@@ -1,68 +1,122 @@
|
|||||||
[](https://www.buymeacoffee.com/rodydavis)
|
# Flutter Vibrate
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WSH3GVC49GNNJ)
|
[](https://pub.dev/packages/flutter_vibrate)
|
||||||

|
|
||||||
[](https://github.com/rodydavis/flutter_vibrate)
|
|
||||||
[](https://pub.dev/packages/flutter_vibrate)
|
|
||||||
|
|
||||||
# Vibrate
|
A Flutter plugin to provide haptic feedback on iOS and Android. This package unifies the haptic feedback APIs, allowing for consistent vibration patterns and feedback types across both platforms.
|
||||||
|
|
||||||
A Flutter plugin to vibrate the device.
|
| Platform | Support |
|
||||||
This uses all the current Haptic Feedback APIs from Apple and provides similar feedback on Android.
|
| :--- | :---: |
|
||||||
|
| Android | ✅ |
|
||||||
|
| iOS | ✅ |
|
||||||
|
| macOS | ❌ |
|
||||||
|
| Web | ❌ |
|
||||||
|
| Linux | ❌ |
|
||||||
|
| Windows | ❌ |
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Device Vibration**: Trigger standard vibrations or custom patterns (Android).
|
||||||
|
- **Haptic Feedback**: Access platform-specific haptic feedback constants (Impact, Selection, Success, Warning, Error, etc.).
|
||||||
|
- **Type Safety**: Built with Pigeon for type-safe communication between Flutter and native platforms.
|
||||||
|
- **Modern Android Support**: Uses `View.performHapticFeedback` for broad compatibility and adheres to modern Android haptic standards.
|
||||||
|
- **iOS Haptics**: Uses `UIImpactFeedbackGenerator` and `UINotificationFeedbackGenerator` for rich haptic experiences on iOS 10+.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
Make sure you add the following permissions to your Android Manifest
|
### Installation
|
||||||
``` xml
|
|
||||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
Add `flutter_vibrate` to your `pubspec.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dependencies:
|
||||||
|
flutter_vibrate: ^1.4.0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Android Setup
|
||||||
|
|
||||||
|
Add the vibration permission to your `AndroidManifest.xml` (`android/app/src/main/AndroidManifest.xml`):
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
|
</manifest>
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note**: While `vibrate()` requires this permission, many haptic feedback types (like selection, impact) may work without it on some Android versions using the View-based API. However, it is recommended to include it for full functionality.
|
||||||
|
|
||||||
|
### iOS Setup
|
||||||
|
|
||||||
|
No additional configuration is required. The plugin uses `AudioServicesPlaySystemSound` and `UIFeedbackGenerator` which are available by default.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
Import the package:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
// Import package
|
|
||||||
import 'package:flutter_vibrate/flutter_vibrate.dart';
|
import 'package:flutter_vibrate/flutter_vibrate.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
### Vibration
|
### Basic Vibration
|
||||||
|
|
||||||
|
Check for device capabilities and vibrate:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
// Check if the device can vibrate
|
// Check if the device can vibrate
|
||||||
bool canVibrate = await Vibrate.canVibrate;
|
bool canVibrate = await Vibrate.canVibrate;
|
||||||
|
|
||||||
// Vibrate
|
if (canVibrate) {
|
||||||
// Vibration duration is a constant 500ms because
|
// Vibrate for 500ms
|
||||||
// it cannot be set to a specific duration on iOS.
|
|
||||||
Vibrate.vibrate();
|
Vibrate.vibrate();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
// Vibrate with pauses between each vibration
|
### Vibration Patterns
|
||||||
final Iterable<Duration> pauses = [
|
|
||||||
const Duration(milliseconds: 500),
|
You can create custom patterns by specifying a list of pauses. The pattern alternates between vibrating and pausing.
|
||||||
const Duration(milliseconds: 1000),
|
|
||||||
const Duration(milliseconds: 500),
|
> **Android**: Supports custom patterns with variable pauses.
|
||||||
|
>
|
||||||
|
> **iOS**: The OS does not support fine-grained custom patterns. This method will vibrate once for each interval in the list.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
final Iterable<Duration> pauses = const [
|
||||||
|
Duration(milliseconds: 500), // Vibrate
|
||||||
|
Duration(milliseconds: 1000), // Wait
|
||||||
|
Duration(milliseconds: 500), // Vibrate
|
||||||
];
|
];
|
||||||
// vibrate - sleep 0.5s - vibrate - sleep 1s - vibrate - sleep 0.5s - vibrate
|
|
||||||
Vibrate.vibrateWithPauses(pauses);
|
Vibrate.vibrateWithPauses(pauses);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Haptic Feedback
|
### Haptic Feedback
|
||||||
|
|
||||||
|
Trigger specific haptic feedback types to enhance user interaction:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
// Choose from any of these available methods
|
// Impact (light collision)
|
||||||
enum FeedbackType {
|
Vibrate.feedback(FeedbackType.impact);
|
||||||
success,
|
|
||||||
error,
|
|
||||||
warning,
|
|
||||||
selection,
|
|
||||||
impact,
|
|
||||||
heavy,
|
|
||||||
medium,
|
|
||||||
light
|
|
||||||
}
|
|
||||||
|
|
||||||
var _type = FeedbackType.impact;
|
// Selection (scroll tick)
|
||||||
Vibrate.feedback(_type);
|
Vibrate.feedback(FeedbackType.selection);
|
||||||
|
|
||||||
|
// Success (task completion)
|
||||||
|
Vibrate.feedback(FeedbackType.success);
|
||||||
|
|
||||||
|
// Warning (potential issue)
|
||||||
|
Vibrate.feedback(FeedbackType.warning);
|
||||||
|
|
||||||
|
// Error (task failure)
|
||||||
|
Vibrate.feedback(FeedbackType.error);
|
||||||
|
|
||||||
|
// Heavy Impact
|
||||||
|
Vibrate.feedback(FeedbackType.heavy);
|
||||||
|
|
||||||
|
// Medium Impact
|
||||||
|
Vibrate.feedback(FeedbackType.medium);
|
||||||
|
|
||||||
|
// Light Impact
|
||||||
|
Vibrate.feedback(FeedbackType.light);
|
||||||
```
|
```
|
||||||
## Documentation
|
|
||||||
#### Android
|
|
||||||
|
|
||||||
https://developer.android.com/reference/android/view/HapticFeedbackConstants
|
## Contributing
|
||||||
|
|
||||||
#### iOS
|
|
||||||
|
|
||||||
https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/
|
|
||||||
|
|
||||||
|
Contributions are welcome! If you find a bug or want to add a feature, please file an issue or submit a pull request.
|
||||||
|
|||||||
@@ -1,16 +1,106 @@
|
|||||||
# example
|
# flutter_vibrate Example
|
||||||
|
|
||||||
A new Flutter project.
|
This example app demonstrates how to use the `flutter_vibrate` plugin to trigger device vibrations and haptic feedback.
|
||||||
|
|
||||||
|
## API Reference & Usage
|
||||||
|
|
||||||
|
Below is an exhaustive list of all exposed methods and haptic feedback types available in the `flutter_vibrate` package.
|
||||||
|
|
||||||
|
### 1. Check Capabilities
|
||||||
|
|
||||||
|
Check if the current device has the hardware to support vibration.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
bool canVibrate = await Vibrate.canVibrate;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Standard Vibration
|
||||||
|
|
||||||
|
Trigger a standard vibration (500ms on Android; system default on iOS).
|
||||||
|
|
||||||
|
```dart
|
||||||
|
Vibrate.vibrate();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Vibration Patterns (Android)
|
||||||
|
|
||||||
|
Trigger a custom vibration pattern by specifying durations for [vibrate, wait, vibrate...].
|
||||||
|
*On iOS, this will vibrate once for each duration provided, as fine-grained patterns are not supported.*
|
||||||
|
|
||||||
|
```dart
|
||||||
|
final Iterable<Duration> pauses = [
|
||||||
|
const Duration(milliseconds: 500), // Vibrate
|
||||||
|
const Duration(milliseconds: 1000), // Wait
|
||||||
|
const Duration(milliseconds: 500), // Vibrate
|
||||||
|
];
|
||||||
|
|
||||||
|
Vibrate.vibrateWithPauses(pauses);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Haptic Feedback
|
||||||
|
|
||||||
|
Trigger specific haptic feedback to enhance user interactions.
|
||||||
|
|
||||||
|
#### Success
|
||||||
|
Indicates that a task has completed successfully.
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.success);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Error
|
||||||
|
Indicates that a task has failed.
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.error);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Warning
|
||||||
|
Indicates a warning or potential issue.
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.warning);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Selection
|
||||||
|
Indicates a selection change (e.g., snapping to a value, scrolling through a list).
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.selection);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Impact
|
||||||
|
Provides a physical impact feedback (e.g., a collision or thud).
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.impact);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Heavy
|
||||||
|
Provides a heavy mass impact.
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.heavy);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Medium
|
||||||
|
Provides a medium mass impact.
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.medium);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Light
|
||||||
|
Provides a light mass impact.
|
||||||
|
```dart
|
||||||
|
Vibrate.feedback(FeedbackType.light);
|
||||||
|
```
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
1. **Run the app**:
|
||||||
|
```bash
|
||||||
|
flutter run
|
||||||
|
```
|
||||||
|
2. **Explore**: Tap the tiles in the app to feel each of the vibrations and feedbacks listed above.
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
## Android Permissions
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
The example app includes the necessary permission in [`android/app/src/main/AndroidManifest.xml`](android/app/src/main/AndroidManifest.xml):
|
||||||
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter, view our
|
```xml
|
||||||
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
samples, guidance on mobile development, and a full API reference.
|
```
|
||||||
|
|||||||
@@ -4,34 +4,60 @@ import 'src/messages.g.dart';
|
|||||||
|
|
||||||
export 'src/messages.g.dart' show VibrateApi;
|
export 'src/messages.g.dart' show VibrateApi;
|
||||||
|
|
||||||
|
/// A set of feedback types that can be used to provide haptic feedback.
|
||||||
enum FeedbackType {
|
enum FeedbackType {
|
||||||
|
/// Indicates a task has completed successfully.
|
||||||
success,
|
success,
|
||||||
|
|
||||||
|
/// Indicates a task has failed or an error occurred.
|
||||||
error,
|
error,
|
||||||
|
|
||||||
|
/// Indicates a warning or caution.
|
||||||
warning,
|
warning,
|
||||||
|
|
||||||
|
/// Indicates a selection change (e.g., scrolling through a list).
|
||||||
selection,
|
selection,
|
||||||
|
|
||||||
|
/// Provides a heavy physical impact.
|
||||||
impact,
|
impact,
|
||||||
|
|
||||||
|
/// Provides a heavy vibration.
|
||||||
heavy,
|
heavy,
|
||||||
|
|
||||||
|
/// Provides a medium vibration.
|
||||||
medium,
|
medium,
|
||||||
|
|
||||||
|
/// Provides a light vibration.
|
||||||
light,
|
light,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A class that provides access to the device's vibration hardware.
|
||||||
class Vibrate {
|
class Vibrate {
|
||||||
static final VibrateApi _api = VibrateApi();
|
static final VibrateApi _api = VibrateApi();
|
||||||
static const Duration _defaultVibrationDuration = Duration(milliseconds: 500);
|
static const Duration _defaultVibrationDuration = Duration(milliseconds: 500);
|
||||||
|
|
||||||
/// Vibrate for 500ms on Android, and for the default time on iOS (about 500ms as well)
|
/// Vibrates the device for 500ms on Android, and for the default system vibration duration on iOS.
|
||||||
static Future<void> vibrate() async {
|
static Future<void> vibrate() async {
|
||||||
await _api.vibrate(500);
|
await _api.vibrate(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the device can actually vibrate or not
|
/// Checks if the device has vibration hardware.
|
||||||
|
///
|
||||||
|
/// Returns `true` if the device can vibrate, `false` otherwise.
|
||||||
static Future<bool> get canVibrate async {
|
static Future<bool> get canVibrate async {
|
||||||
return _api.canVibrate();
|
return _api.canVibrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Vibrates with [pauses] in between each vibration
|
/// Vibrates the device with a specific pattern of pauses.
|
||||||
/// Will always vibrate once before the first pause
|
///
|
||||||
/// and once after the last pause
|
/// The [pauses] iterable defines the duration of silence in between vibrations.
|
||||||
|
/// The pattern will always start with a vibration, followed by the first pause,
|
||||||
|
/// then another vibration, and so on, ending with a final vibration.
|
||||||
|
///
|
||||||
|
/// For example, if [pauses] is `[Duration(seconds: 1)]`, the device will:
|
||||||
|
/// 1. Vibrate (default duration)
|
||||||
|
/// 2. Wait for 1 second
|
||||||
|
/// 3. Vibrate (default duration)
|
||||||
static Future<void> vibrateWithPauses(Iterable<Duration> pauses) async {
|
static Future<void> vibrateWithPauses(Iterable<Duration> pauses) async {
|
||||||
for (final Duration d in pauses) {
|
for (final Duration d in pauses) {
|
||||||
await vibrate();
|
await vibrate();
|
||||||
@@ -44,6 +70,10 @@ class Vibrate {
|
|||||||
await vibrate();
|
await vibrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provides haptic feedback corresponding to the specified [type].
|
||||||
|
///
|
||||||
|
/// This uses the platform's native haptic feedback mechanisms (e.g., `UINotificationFeedbackGenerator` on iOS,
|
||||||
|
/// `View.performHapticFeedback` on Android).
|
||||||
static Future<void> feedback(FeedbackType type) async {
|
static Future<void> feedback(FeedbackType type) async {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FeedbackType.impact:
|
case FeedbackType.impact:
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ PlatformException _createConnectionError(String channelName) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class _PigeonCodec extends StandardMessageCodec {
|
class _PigeonCodec extends StandardMessageCodec {
|
||||||
const _PigeonCodec();
|
const _PigeonCodec();
|
||||||
@override
|
@override
|
||||||
@@ -41,9 +40,13 @@ class VibrateApi {
|
|||||||
/// Constructor for [VibrateApi]. The [binaryMessenger] named argument is
|
/// Constructor for [VibrateApi]. The [binaryMessenger] named argument is
|
||||||
/// available for dependency injection. If it is left null, the default
|
/// available for dependency injection. If it is left null, the default
|
||||||
/// BinaryMessenger will be used which routes to the host platform.
|
/// BinaryMessenger will be used which routes to the host platform.
|
||||||
VibrateApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
|
VibrateApi({
|
||||||
: pigeonVar_binaryMessenger = binaryMessenger,
|
BinaryMessenger? binaryMessenger,
|
||||||
pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
String messageChannelSuffix = '',
|
||||||
|
}) : pigeonVar_binaryMessenger = binaryMessenger,
|
||||||
|
pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty
|
||||||
|
? '.$messageChannelSuffix'
|
||||||
|
: '';
|
||||||
final BinaryMessenger? pigeonVar_binaryMessenger;
|
final BinaryMessenger? pigeonVar_binaryMessenger;
|
||||||
|
|
||||||
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
||||||
@@ -51,7 +54,8 @@ class VibrateApi {
|
|||||||
final String pigeonVar_messageChannelSuffix;
|
final String pigeonVar_messageChannelSuffix;
|
||||||
|
|
||||||
Future<bool> canVibrate() async {
|
Future<bool> canVibrate() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.canVibrate$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.canVibrate$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -78,13 +82,16 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> vibrate(int duration) async {
|
Future<void> vibrate(int duration) async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.vibrate$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.vibrate$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
binaryMessenger: pigeonVar_binaryMessenger,
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[duration]);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
|
||||||
|
<Object?>[duration],
|
||||||
|
);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
if (pigeonVar_replyList == null) {
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
throw _createConnectionError(pigeonVar_channelName);
|
||||||
@@ -100,7 +107,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> impact() async {
|
Future<void> impact() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.impact$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.impact$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -122,7 +130,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> selection() async {
|
Future<void> selection() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.selection$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.selection$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -144,7 +153,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> success() async {
|
Future<void> success() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.success$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.success$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -166,7 +176,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> warning() async {
|
Future<void> warning() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.warning$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.warning$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -188,7 +199,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> error() async {
|
Future<void> error() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.error$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.error$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -210,7 +222,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> heavy() async {
|
Future<void> heavy() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.heavy$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.heavy$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -232,7 +245,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> medium() async {
|
Future<void> medium() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.medium$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.medium$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
@@ -254,7 +268,8 @@ class VibrateApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> light() async {
|
Future<void> light() async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_vibrate.VibrateApi.light$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.flutter_vibrate.VibrateApi.light$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
pigeonVar_channelName,
|
pigeonVar_channelName,
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
name: flutter_vibrate
|
name: flutter_vibrate
|
||||||
description: A Haptic Feedback plugin.
|
description: A Haptic Feedback and Vibration plugin.
|
||||||
version: 1.3.0
|
version: 1.4.0
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.10.4
|
sdk: ^3.10.4
|
||||||
flutter: ^3.38.5
|
flutter: ^3.38.5
|
||||||
maintainer: Rody Davis (@rodydavis)
|
maintainer: Rody Davis (@rodydavis)
|
||||||
homepage: https://github.com/rodydavis/plugins
|
homepage: https://github.com/rodydavis/packages.dart
|
||||||
repository: https://github.com/rodydavis/flutter_vibrate
|
repository: https://github.com/rodydavis/packages.dart
|
||||||
resolution: workspace
|
resolution: workspace
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user