otp_resend_timer 1.0.0
otp_resend_timer: ^1.0.0 copied to clipboard
Flutter widget that handle OTP resend functionality with customizable UI, animations, and callback support.
import 'package:flutter/material.dart';
import 'package:otp_resend_timer/otp_resend_timer.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'OTP Resend Timer Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late OtpResendTimerController _controller;
final TextEditingController _otpController = TextEditingController();
final List<FocusNode> _focusNodes = List.generate(4, (index) => FocusNode());
final List<TextEditingController> _digitControllers =
List.generate(4, (index) => TextEditingController());
@override
void initState() {
super.initState();
_controller = OtpResendTimerController(initialTime: 10);
}
@override
void dispose() {
_controller.dispose();
_otpController.dispose();
for (var node in _focusNodes) {
node.dispose();
}
for (var controller in _digitControllers) {
controller.dispose();
}
super.dispose();
}
void _onResendClicked() {
// Resend OTP logic here
}
void _onDigitInput(String value, int index) {
if (value.length == 1) {
if (index < 3) {
_focusNodes[index + 1].requestFocus();
} else {
// Last digit entered, hide keyboard
FocusManager.instance.primaryFocus?.unfocus();
}
}
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
backgroundColor: theme.colorScheme.inversePrimary,
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 30),
// Example of a mock OTP input field
Container(
margin: const EdgeInsets.symmetric(horizontal: 24),
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey.shade300),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.shade200,
blurRadius: 10,
offset: const Offset(0, 5),
),
],
),
child: Column(
children: [
const Text(
'Enter OTP Code',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
const Text(
'We\'ve sent a verification code to your phone',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
const SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(
4,
(index) => SizedBox(
width: 50,
height: 60,
child: TextField(
controller: _digitControllers[index],
focusNode: _focusNodes[index],
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
maxLength: 1,
onChanged: (value) => _onDigitInput(value, index),
decoration: InputDecoration(
counterText: '',
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: theme.primaryColor),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: theme.primaryColor, width: 2),
),
),
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
),
),
),
const SizedBox(height: 30),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
// String otp = _digitControllers.map((c) => c.text).join();
},
style: ElevatedButton.styleFrom(
backgroundColor: theme.primaryColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text('Verify'),
),
),
const SizedBox(height: 20),
// OtpResendTimer
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: OtpResendTimer(
controller: _controller,
onResendClicked: _onResendClicked,
autoStart: true,
timerMessage: 'Resend OTP in ',
readyMessage: 'You can now resend the code',
holdMessage: 'Start timer to enable resend',
resendMessage: 'Resend',
timerMessageStyle: TextStyle(
color: theme.primaryColor,
fontSize: 12,
),
resendMessageStyle: TextStyle(
color: theme.primaryColor,
fontSize: 12,
),
),
),
],
),
),
],
),
),
),
);
}
}
copied to clipboard