Reputation: 23
I have a counter in my app. I display the counter second like this.
Text(
"$_start second",
style: GoogleFonts.nunitoSans(
color: Colors.amber,
fontWeight: FontWeight.bold,
fontSize: 20.0.sp),
textAlign: TextAlign.center,
),
Also I have function for the counter. It starts after the press the button.
void startTimer() {
const oneSec = Duration(seconds: 1);
_timer = Timer.periodic(
oneSec,
(Timer timer) {
if (_start == 0) {
setState(() {
timer.cancel();
_isButtonDisabled = false;
});
} else {
setState(() {
_start--;
});
}
},
);
}
My problem is I have a Pinput widget to enter the OTP. After startTimer function starts working, every widgets are renewed and reseted. Because of that, I cant enter the OTP. After my researches, I found StatefulBuilder widget. I used this on some Widgets with setState function and it worked. But I dont have setState funcion in Text Widget. startTimer function has. I could not find any usage like this. How can I do that.
All Dart Code
class SignUpVerifyClientNumber extends StatefulWidget {
const SignUpVerifyClientNumber({super.key, required this.userId});
@override
State<SignUpVerifyClientNumber> createState() =>
_SignUpVerifyClientNumberState();
final userId;
}
class _SignUpVerifyClientNumberState extends State<SignUpVerifyClientNumber> {
late int otpCode;
late Timer _timer;
int _start = 150;
late bool _isButtonDisabled;
@override
void initState() {
_isButtonDisabled = false;
super.initState();
}
void startTimer() {
const oneSec = Duration(seconds: 1);
_timer = Timer.periodic(
oneSec,
(Timer timer) {
if (_start == 0) {
setState(() {
timer.cancel();
_isButtonDisabled = false;
});
} else {
setState(() {
_start--;
});
}
},
);
}
void sendOtp() {
var rng = Random();
int refCode = rng.nextInt(9000) + 1000;
var smsContent = "$otpText$refCode";
sendSMS(smsContent, "111111111");
_isButtonDisabled = true;
startTimer();
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light.copyWith(
statusBarColor: appColor,
));
final pinController = TextEditingController();
final focusNode = FocusNode();
return ScreenUtilInit(
designSize: const Size(360, 690),
minTextAdapt: true,
splitScreenMode: true,
builder: (_, child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: whiteColor,
body: SingleChildScrollView(
child: Center(
child: Column(
children: [
Center(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 0, horizontal: 35),
child: Column(
children: [
Pinput(
controller: pinController,
focusNode: focusNode,
defaultPinTheme: defaultPinTheme,
separatorBuilder: (index) =>
SizedBox(width: 8.w),
validator: (value) {
if (value == otpCode.toString()) {
context.push(
'/signUpRefCode/${widget.userId}');
} else {
return 'Pin is incorrect';
}
return null;
},
hapticFeedbackType:
HapticFeedbackType.lightImpact,
onCompleted: (pin) {
debugPrint('onCompleted: $pin');
},
onChanged: (value) {
debugPrint('onChanged: $value');
},
cursor: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
margin: EdgeInsets.only(bottom: 9.h),
width: 22.w,
height: 1.h,
color: const Color.fromRGBO(
23, 171, 144, 1),
),
],
),
focusedPinTheme: defaultPinTheme.copyWith(
decoration:
defaultPinTheme.decoration!.copyWith(
borderRadius: BorderRadius.circular(8.sp),
border: Border.all(
color: const Color.fromRGBO(
23, 171, 144, 1)),
),
),
submittedPinTheme: defaultPinTheme.copyWith(
decoration:
defaultPinTheme.decoration!.copyWith(
color: lightAppColor,
borderRadius:
BorderRadius.circular(19.sp),
border: Border.all(
color: const Color.fromRGBO(
23, 171, 144, 1)),
),
),
errorPinTheme: defaultPinTheme.copyBorderWith(
border: Border.all(color: Colors.redAccent),
),
),
Gap(30.h),
Text(
didntReceiveAnyCodeString,
style: GoogleFonts.nunitoSans(
color: Colors.black38,
fontWeight: FontWeight.bold,
fontSize: 12.0.sp),
),
Gap(10.h),
Text(
"$_start second",
style: GoogleFonts.nunitoSans(
color: Colors.amber,
fontWeight: FontWeight.bold,
fontSize: 20.0.sp),
textAlign: TextAlign.center,
),
Gap(10.h),
SizedBox(
width: MediaQuery.of(context).size.width / 2,
height: 40.h,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: firstAppColor,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.sp),
),
),
onPressed:
_isButtonDisabled ? null : sendOtp,
child: Text(
resendNewCodeString,
style: TextStyle(
color: Colors.white,
fontFamily:
GoogleFonts.openSans().fontFamily,
fontWeight: FontWeight.w600,
fontSize: 13.0.sp),
),
),
),
],
),
),
),
],
),
),
),
),
),
);
});
}
final defaultPinTheme = PinTheme(
width: 50.w,
height: 50.h,
textStyle: const TextStyle(
fontSize: 22,
color: Color.fromRGBO(30, 60, 87, 1),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(19),
border:
Border.all(color: const Color.fromRGBO(23, 171, 144, 0.4), width: 4),
),
);
}
Upvotes: 0
Views: 76