The timer and validation of the bottom sheet are not functioning as desired in flutter

24 views Asked by At

I did

  1. Tried using StreamBuilder for the timer. - failed
  2. 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,
                          ),
                        );
                      }),
0

There are 0 answers