I did
- Tried using StreamBuilder for the timer. - failed
- Attempted state management within the modal using StatefulBuilder for both the timer and validation. - failed
final _formKey = GlobalKey<FormState>();
final _validatorKey = GlobalKey<FormState>();
int totalSeconds = 180;
Timer? timer;
Duration duration = Duration(minutes: 3);
bool isSheetOpen = false;
void dispose() {
timer?.cancel();
super.dispose();
}
void startTimer() {
timer?.cancel();
timer = Timer.periodic(Duration(seconds: 1), (timer) {});
}
Future<dynamic> _validate_modal(BuildContext context) {
return showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)),
),
builder: (context) {
return StatefulBuilder(builder: (context, StateSetter bottomState) {
startTimer();
return Container(
padding: MediaQuery.of(context).viewInsets,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Center(
child: Text(
' input validation number',
style: TextStyle(
fontFamily: 'Pretendard',
fontWeight: FontWeight.w500,
fontSize: 16),
),
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: Form(
key: _validatorKey,
child: TextFormField(
controller: _validatorController,
validator: (value) {
if (value == null || value.isEmpty) {
return ' input your validation number';
} else if (value.length != 6) {
return 'Please input a six-digit validation number.';
}
return null;
},
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(6),
],
style: TextStyle(
fontFamily: 'Pretendard',
fontSize: 30,
fontWeight: FontWeight.w300),
cursorColor: Colors.black,
textAlign: TextAlign.center,
// 텍스트 가운데 정렬
decoration: InputDecoration(
border: InputBorder.none, // 텍스트 입력 필드의 테두리를 없앰
),
),
),
),
StreamBuilder(
stream: Stream.periodic(Duration(seconds: 1)),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {}
return Text(
'${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}',
style: TextStyle(
fontFamily: 'Pretendard',
fontSize: 14,
fontWeight: FontWeight.w300,
),
);
}),
Padding(
padding: const EdgeInsets.only(top: 35, bottom: 10),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
width: MediaQuery.of(context).size.width * 1,
height: 56,
child: FilledButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
side: BorderSide(
color: Colors.black, width: 1.0)))),
onPressed: () {
final form = _formKey.currentState!;
if (form.validate()) {
Navigator.of(context).pop();
_contractSheet(context);
} else {
null;
print('Validation failed.');
}
},
child: Center(
child: Text(
'다음',
style: TextStyle(
fontFamily: 'Pretendard',
fontSize: 16,
fontWeight: FontWeight.w700,
color: Colors.black),
),
)),
),
),
),
],
),
),
);
});
},
);
}
Below is the problematic code which renders a timer. However, it does not decrement by 1 second in real-time. How should this be modified?
I've tried several attempts, but I'm still unsure. Is there something I might be missing?
StreamBuilder(
stream: Stream.periodic(Duration(seconds: 1)),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {}
return Text(
'${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}',
style: TextStyle(
fontFamily: 'Pretendard',
fontSize: 14,
fontWeight: FontWeight.w300,
),
);
}),