Search code examples
flutterdartstatelesswidget

Text not getting updated with new value in flutter


Hi I am new to flutter and experimenting with statefull widget. I am trying to build a timer and want to show it in a Text.

This is my widget class.

class MobileVerification extends StatefulWidget {
  static const String MOBILE = 'mobile';
  final Map<String, dynamic> args;

  MobileVerification(this.args);

  @override
  State<StatefulWidget> createState() {
    return MobileVerificationState(args);
  }
}

This is my State class

class MobileVerificationState extends State<MobileVerification> {
  int remainingTime = 30;
  Timer timer;
  bool isResendBtnEnabled = false;

  MobileVerificationState(this.args);

  @override
  void initState() {
    super.initState();
    startResendTimer();
  }

  startResendTimer() {
    timer = new Timer.periodic(new Duration(seconds: 1), (time) {
      setState(() {
        remainingTime -= 1;
      });
      if (remainingTime == 0) {
           time.cancel();
           setState(() {
           isResendBtnEnabled = true;
        });
      }
    });
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CustomScreenBg(
        body: _getOtpVerificationPage());
  }

  _getOtpVerificationPage() {
    return Container(
      margin: EdgeInsets.only(top: 24, bottom: 24, left: 12, right: 12),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          getResendWidget(),
          CustomButton(
            AppString.verify,
            isValidateBtnEnabled ? _onValidate : null,
            textColor: AppColor.WHITE.color,
            bgColor: AppColor.PRIMARY.color,
          ),
        ],
      ),
    );
  }

  Widget getResendWidget() {
    Logger.d(remainingTime.toString()); // Here I am getting changed value.
    if (isResendBtnEnabled) {
      return CustomButton(
        AppString.resend,
        _onResend,
        textColor: AppColor.WHITE.color,
        bgColor: AppColor.PRIMARY.color,
      );
    }
    return RichText(
      text: TextSpan(
        text: 'Resend in ${remainingTime}s',  <== But here value is not getting reflected. It stays same as 30
        style: TextStyle(color: AppColor.GRAY.color, fontSize: 18),
      ),
    );
  }
}

Timer is working perfectly fine, and I am getting updated value as well. But the updated value is not getting reflected inside RichText. Can someone point me out, where i am making the mistake? Thanks!!


Solution

  • I was making a mistake. I was using StatefulWidget instead of statelessWidget for inheritance. Hope it can help someone. I have created my own custom widget to use. Structure of my widget is follows:

    class CustomScreenBg extends StatefulWidget {
      final String title;
      final Widget body;
    
      CustomScreenBg(this.title, this.body);
    
      @override
      State<StatefulWidget> createState() {
       return _CustomScreenBgState(title, body);
      }
    }
    
    class _CustomScreenBgState extends State<CustomScreenBg> {
      final String title;
      final Widget body;
    
      _CustomScreenBgState(this.title, this.body);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(title),
          ),
          backgroundColor: AppColor.SNOW_WHITE.color,
          body: SingleChildScrollView(child: body),
          resizeToAvoidBottomInset: true,
        );
      }
    
    }
    
    
    

    I changed it to following and it is working fine.

    class CustomScreenBg extends StatelessWidget {
      final String title;
      final Widget body;
    
      CustomScreenBg(this.title, this.body);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(title),
          ),
          backgroundColor: AppColor.SNOW_WHITE.color,
          body: SingleChildScrollView(child: body),
          resizeToAvoidBottomInset: true,
        );
      }
    }