flutter_pin_text_field 2.0.0
flutter_pin_text_field: ^2.0.0 copied to clipboard
A highly customizable PIN input widget for Flutter with extensive styling options, multiple border types, and reliable input handling.
import 'package:flutter/material.dart';
import 'package:flutter_pin_text_field/flutter_pin_text_field.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PIN TextField Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const PinTextFieldDemo(),
);
}
}
class PinTextFieldDemo extends StatefulWidget {
const PinTextFieldDemo({super.key});
@override
State<PinTextFieldDemo> createState() => _PinTextFieldDemoState();
}
class _PinTextFieldDemoState extends State<PinTextFieldDemo> {
String _currentPin = '';
String _completedPin = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('PIN TextField Demo'),
centerTitle: true,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Basic style
_buildSection(
title: 'Basic Style (6 digits)',
child: PinTextField(
pinLength: 6,
autoFocus: true,
onChanged: (pin) {
setState(() {
_currentPin = pin;
});
},
onCompleted: (pin) {
setState(() {
_completedPin = pin;
});
_showCompletedDialog(pin);
},
),
),
const SizedBox(height: 20),
// Custom style - outline border
_buildSection(
title: 'Outline Border Style (4 digits)',
child: PinTextField(
pinLength: 4,
style: const PinStyle(
width: 60,
height: 60,
spacing: 15,
fontSize: 20,
borderType: PinBorderType.outline,
borderRadius: 12,
borderColor: Colors.grey,
focusedBorderColor: Colors.blue,
borderWidth: 2,
focusedBorderWidth: 3,
),
onCompleted: (pin) => _showCompletedDialog(pin),
),
),
const SizedBox(height: 20),
// With background color
_buildSection(
title: 'With Background Color (5 digits)',
child: PinTextField(
pinLength: 5,
style: const PinStyle(
width: 55,
height: 55,
spacing: 10,
fontSize: 18,
borderType: PinBorderType.outline,
borderRadius: 8,
backgroundColor: Color(0xFFF5F5F5),
focusedBackgroundColor: Color(0xFFE3F2FD),
borderColor: Colors.transparent,
focusedBorderColor: Colors.blue,
textColor: Colors.black87,
),
onCompleted: (pin) => _showCompletedDialog(pin),
),
),
const SizedBox(height: 20),
// Underline style
_buildSection(
title: 'Underline Style (6 digits)',
child: PinTextField(
pinLength: 6,
style: const PinStyle(
width: 40,
height: 50,
spacing: 20,
fontSize: 22,
borderType: PinBorderType.underline,
borderColor: Colors.grey,
focusedBorderColor: Colors.deepPurple,
borderWidth: 2,
focusedBorderWidth: 3,
textColor: Colors.deepPurple,
cursorColor: Colors.deepPurple,
),
onCompleted: (pin) => _showCompletedDialog(pin),
),
),
const SizedBox(height: 20),
// No border style
_buildSection(
title: 'No Border Style (4 digits)',
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(12),
),
child: PinTextField(
pinLength: 4,
style: const PinStyle(
width: 50,
height: 50,
spacing: 15,
fontSize: 24,
borderType: PinBorderType.none,
backgroundColor: Colors.white,
focusedBackgroundColor: Color(0xFFE8F5E8),
textColor: Colors.green,
cursorColor: Colors.green,
),
onCompleted: (pin) => _showCompletedDialog(pin),
),
),
),
const SizedBox(height: 30),
// Status display
_buildSection(
title: 'Input Status',
child: Column(
children: [
Text(
'Current Input: $_currentPin',
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 8),
Text(
'Completed Input: $_completedPin',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
],
),
),
],
),
),
);
}
Widget _buildSection({required String title, required Widget child}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
const SizedBox(height: 12),
Center(child: child),
],
);
}
void _showCompletedDialog(String pin) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('PIN Input Completed'),
content: Text('Your PIN is: $pin'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('OK'),
),
],
),
);
}
}