Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tkko/flutter_pinput
Flutter package to create Pin code input text field with every pixel customization possibility 🎨 with beautiful animations, iOS autofill, Android autofill
https://github.com/tkko/flutter_pinput
android-autofill autofill code flutter flutter-package flutter-pin-code flutter-widget ios-autofill otp phone-verification pin pincode sms smsautofill smsretrieverapi smsuserconsentapi verification verification-code
Last synced: about 7 hours ago
JSON representation
Flutter package to create Pin code input text field with every pixel customization possibility 🎨 with beautiful animations, iOS autofill, Android autofill
- Host: GitHub
- URL: https://github.com/tkko/flutter_pinput
- Owner: Tkko
- License: mit
- Created: 2018-10-24T19:08:24.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2025-01-15T14:25:43.000Z (10 days ago)
- Last Synced: 2025-01-20T00:43:53.554Z (5 days ago)
- Topics: android-autofill, autofill, code, flutter, flutter-package, flutter-pin-code, flutter-widget, ios-autofill, otp, phone-verification, pin, pincode, sms, smsautofill, smsretrieverapi, smsuserconsentapi, verification, verification-code
- Language: Dart
- Homepage: https://pub.dev/packages/pinput
- Size: 7.66 MB
- Stars: 787
- Watchers: 7
- Forks: 181
- Open Issues: 21
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
Flutter pin code input
Need anything Flutter related? Reach out on LinkedIn
[![Pub package](https://img.shields.io/pub/v/pinput.svg)](https://pub.dev/packages/pinput)
[![Github starts](https://img.shields.io/github/stars/tkko/flutter_pinput.svg?style=flat&logo=github&colorB=deeppink&label=stars)](https://github.com/tkko/flutter_pinput)
[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://github.com/tenhobi/effective_dart)
[![pub package](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT)Flutter Pinput is a package that provides an easy-to-use and customizable Pin code input field. It offers several features such as animated decoration switching, form validation, SMS autofill, custom cursor, copying from clipboard, and more. It also provides beautiful examples that you can choose from.
## Features:
- Animated Decoration Switching
- Form validation
- SMS Autofill on iOS
- SMS Autofill on Android
- Standard Cursor
- Custom Cursor
- Cursor Animation
- Copy From Clipboard
- Ready For Custom Keyboard
- Standard Paste option
- Obscuring Character
- Obscuring Widget
- Haptic Feedback
- Close Keyboard After Completion
- Beautiful [Examples](https://github.com/Tkko/Flutter_PinPut/tree/master/example/lib)## Support
PRs Welcome
Discord [Channel](https://rebrand.ly/qwc3s0d)
[Examples](https://github.com/Tkko/Flutter_PinPut/tree/master/example/lib) app on Github has multiple templates to choose from
Don't forget to give it a star ⭐
## Demo
| [Live Demo](https://rebrand.ly/6390b8) | Rounded With Shadows | Rounded With Cursor |
| - | - | - |
| | | || Rounded Filled | With Bottom Cursor | Filled |
| - | - | - |
| | | |## Getting Started
The pin has 6 states `default` `focused`, `submitted`, `following`, `disabled`, `error`, you can customize each state by specifying theme parameter.
Pin smoothly animates from one state to another automatically.
`PinTheme Class`| Property | Default/Type |
|-------------|:------------------:|
| width | 56.0 |
| height | 60.0 |
| textStyle | TextStyle() |
| margin | EdgeInsetsGeometry |
| padding | EdgeInsetsGeometry |
| constraints | BoxConstraints |You can use standard Pinput like so
```dart
Widget buildPinPut() {
return Pinput(
onCompleted: (pin) => print(pin),
);
}
```If you want to customize it, create `defaultPinTheme` first.
```dart
final defaultPinTheme = PinTheme(
width: 56,
height: 56,
textStyle: TextStyle(fontSize: 20, color: Color.fromRGBO(30, 60, 87, 1), fontWeight: FontWeight.w600),
decoration: BoxDecoration(
border: Border.all(color: Color.fromRGBO(234, 239, 243, 1)),
borderRadius: BorderRadius.circular(20),
),
);
```if you want all pins to be the same don't pass other theme parameters,
If not, create `focusedPinTheme`, `submittedPinTheme`, `followingPinTheme`, `errorPinTheme` from `defaultPinTheme````dart
final focusedPinTheme = defaultPinTheme.copyDecorationWith(
border: Border.all(color: Color.fromRGBO(114, 178, 238, 1)),
borderRadius: BorderRadius.circular(8),
);final submittedPinTheme = defaultPinTheme.copyWith(
decoration: defaultPinTheme.decoration.copyWith(
color: Color.fromRGBO(234, 239, 243, 1),
),
);
```Put everything together
```dart
final defaultPinTheme = PinTheme(
width: 56,
height: 56,
textStyle: TextStyle(fontSize: 20, color: Color.fromRGBO(30, 60, 87, 1), fontWeight: FontWeight.w600),
decoration: BoxDecoration(
border: Border.all(color: Color.fromRGBO(234, 239, 243, 1)),
borderRadius: BorderRadius.circular(20),
),
);final focusedPinTheme = defaultPinTheme.copyDecorationWith(
border: Border.all(color: Color.fromRGBO(114, 178, 238, 1)),
borderRadius: BorderRadius.circular(8),
);final submittedPinTheme = defaultPinTheme.copyWith(
decoration: defaultPinTheme.decoration.copyWith(
color: Color.fromRGBO(234, 239, 243, 1),
),
);return Pinput(
defaultPinTheme: defaultPinTheme,
focusedPinTheme: focusedPinTheme,
submittedPinTheme: submittedPinTheme,
validator: (s) {
return s == '2222' ? null : 'Pin is incorrect';
},
pinputAutovalidateMode: PinputAutovalidateMode.onSubmit,
showCursor: true,
onCompleted: (pin) => print(pin),
);
```## SMS Autofill
### iOS
Works out of the box, by tapping the code on top of the keyboard
### Android
If you are using [firebase_auth](https://firebase.flutter.dev/docs/auth/phone#verificationcompleted) you have to set `controller'`s value in `verificationCompleted` callback, here is an example code:
``` dart
Pinput(
controller: pinController,
);
```
And set pinController's value in `verificationCompleted` callback:
``` dart
await FirebaseAuth.instance.verifyPhoneNumber(
verificationCompleted: (PhoneAuthCredential credential) {
pinController.setText(credential.smsCode);
},
verificationFailed: (FirebaseAuthException e) {},
codeSent: (String verificationId, int? resendToken) {},
codeAutoRetrievalTimeout: (String verificationId) {},
);
```
---
If you aren't using firebase_auth, you have two options, [SMS Retriever API](https://developers.google.com/identity/sms-retriever/overview?hl=en) and [SMS User Consent API](https://developers.google.com/identity/sms-retriever/user-consent/overview),[SmartAuth](https://pub.dev/packages/smart_auth) is a wrapper package for Flutter for these APIs, so go ahead and add it as a dependency.
###### SMS Retriever API
To use Retriever API you need the App signature - [guide](https://stackoverflow.com/questions/53849023/android-sms-retriever-api-computing-apps-hash-string-problem)
`Note that The App Signature might be different for debug and release mode`
Once you get the app signature, you should include it in the SMS message in you backend like so:
SMS example:
```
Your ExampleApp code is: 123456
kg+TZ3A5qzS
```
[Example Code](/example/lib/demo/sms_retriever_api_example.dart)Sms code will be automatically applied, without user interaction.
###### SMS User Consent API
You don't need the App signature, the user will be prompted to confirm reading the message
[Example Code](/example/lib/demo/user_consent_api_example.dart)## See Example app for more [templates](https://github.com/Tkko/Flutter_PinPut/tree/master/example/lib)
## Tips
- #### Controller
```dart
/// Create Controller
final pinController = TextEditingController();/// Set text programmatically
pinController.setText('1222');/// Append typed character, useful if you are using custom keyboard
pinController.append('1', 4);/// Delete last character
pinController.delete();/// Don't call setText, append, delete in build method, this is just illustration.
return Pinput(
controller: pinController,
);
```- #### Focus
```dart
/// Create FocusNode
final pinputFocusNode = FocusNode();/// Focus pinput
pinputFocusNode.requestFocus();/// UnFocus pinput
pinputFocusNode.unfocus();/// Don't call requestFocus, unfocus in build method, this is just illustration.
return Pinput(
focusNode: pinputFocusNode,
);
```- #### Validation
```dart
/// Create key
final formKey = GlobalKey();/// Validate manually
/// Don't call validate in build method, this is just illustration.
formKey.currentState!.validate();return Form(
key: formKey,
child: Pinput(
// Without Validator
// If true error state will be applied no matter what validator returns
forceErrorState: true,
// Text will be displayed under the Pinput
errorText: 'Error',/// ------------
/// With Validator
/// Auto validate after user tap on keyboard done button, or completes Pinput
pinputAutovalidateMode: PinputAutovalidateMode.onSubmit,
validator: (pin) {
if (pin == '2224') return null;/// Text will be displayed under the Pinput
return 'Pin is incorrect';
},
),
);
```## FAQ
#### autofill isn't working on iOS?
- Make sure you are using real device, not simulator
- Temporary replace Pinput with TextField, and check if autofill works. If, not it's probably a
problem with SMS you are getting, autofill doesn't work with most of the languages
- If you are using non stable version of Flutter that might be cause because something might be
broken inside the Framework#### are you using firebase_auth?
You should set `controller'`s value in `verificationCompleted` callback, here is an example code:
``` dart
Pinput(
controller: pinController,
);
await FirebaseAuth.instance.verifyPhoneNumber(
verificationCompleted: (PhoneAuthCredential credential) {
pinController.setText(credential.smsCode);
},
verificationFailed: (FirebaseAuthException e) {},
codeSent: (String verificationId, int? resendToken) {},
codeAutoRetrievalTimeout: (String verificationId) {},
);
```