Flutter how to clean this input field for pincode

1,540

You don't need to call textEditingController.clear(); inside setState() to clear the value set on the TextEditingController. Move the function outside setState and this should fix the issue.

Share:
1,540
Vitor Araújo
Author by

Vitor Araújo

Programador Engenheira de Software Curioso e querendo construir games Desenvolvedora front end insira o código aqui programer Software engineer Curious and trying to build and program games front end developer enter code here

Updated on December 02, 2022

Comments

  • Vitor Araújo
    Vitor Araújo over 1 year

    I am trying to create this input field for the user to register its pin, however I don't want to call another context screen. So, the point is simple, the user types the pin, the field clears, the text in the screen changes and the user types again , confirming the pin.

    I ran into two problems tho. The field never clears, no matter what I do and when I click the field to type again the state resets back to the first pin input. here is the code for the widgets.

               //Form fields
            StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
              return Column(
                children: [
                  Container(
                    width: 330,
                    child: pinCodeType == 1
                        ? Text("Choose a Pincode",
                            style: TextStyle(color: brandBlue, fontSize: 18))
                        : Text("Repeat your Pincode",
                            style: TextStyle(color: brandBlue, fontSize: 18)),
                  ),
                  Container(
                      height: 90,
                      width: 330,
                      child: pinCodeType == 1
                          ? new PinCodeTextField(
                              enablePinAutofill: false,
                              keyboardAppearance: Brightness.dark,
                              length: 5,
                              obscureText: true,
                              textStyle: TextStyle(color: brandBlue),
                              animationType: AnimationType.scale,
                              keyboardType: TextInputType.numberWithOptions(),
                              autoDisposeControllers: true,
                              pinTheme: PinTheme(
                                  shape: PinCodeFieldShape.underline,
                                  //borderRadius: BorderRadius.circular(5),
                                  fieldHeight: 80,
                                  fieldWidth: 60,
                                  activeColor: brandBlue,
                                  inactiveFillColor: Colors.transparent,
                                  inactiveColor: brandDarkGrey,
                                  activeFillColor: brandWhite,
                                  selectedColor: brandLightBlue,
                                  selectedFillColor: Colors.transparent),
                              animationDuration: Duration(milliseconds: 300),
                              backgroundColor: brandWhite,
                              enableActiveFill: true,
                              errorAnimationController: errorController,
                              controller: textEditingController,
                              onCompleted: (v) {
                                if (pinCodeType == 1) {
                                  pincode1 = v;
                                  print("PINCODE 1 $pincode1");
    
                                  print("PINCODE TYPE $pinCodeType");
    
                                  setState(() {
                                    textEditingController.clear();
                                    pinCodeType = 2;
                                    v = '';
                                  });
                                }
                              },
                              onChanged: (value) {
                                print(value);
                                setState(() {});
                              },
                              beforeTextPaste: (text) {
                                print("Allowing to paste $text");
                                //if you return true then it will show the paste confirmation dialog. Otherwise if false, then nothing will happen.
                                //but you can show anything you want here, like your pop up saying wrong paste format or etc
                                return true;
                              },
                              appContext: context,
                            )
                          : new PinCodeTextField(
                              enablePinAutofill: false,
                              keyboardAppearance: Brightness.dark,
                              length: 5,
                              obscureText: true,
                              textStyle: TextStyle(color: brandBlue),
                              animationType: AnimationType.scale,
                              keyboardType: TextInputType.numberWithOptions(),
                              pinTheme: PinTheme(
                                  shape: PinCodeFieldShape.underline,
                                  //borderRadius: BorderRadius.circular(5),
                                  fieldHeight: 80,
                                  fieldWidth: 60,
                                  activeColor: brandBlue,
                                  inactiveFillColor: Colors.transparent,
                                  inactiveColor: brandDarkGrey,
                                  activeFillColor: brandWhite,
                                  selectedColor: brandLightBlue,
                                  selectedFillColor: Colors.transparent),
                              animationDuration: Duration(milliseconds: 300),
                              backgroundColor: brandWhite,
                              autoDisposeControllers: true,
                              enableActiveFill: true,
                              errorAnimationController: errorController2,
                              controller: textEditingController2,
                              onCompleted: (v) {
                                if (pinCodeType == 2) {
                                  pincode1 = v;
                                  print("PINCODE 2 $pincode2");
    
                                  print("PINCODE TYPE $pinCodeType");
    
                                  setState(() {
                                    v = '';
                                    pinCodeType++;
                                  });
                                }
                              },
                              onChanged: (value) {
                                print(value);
                                setState(() {});
                              },
                              beforeTextPaste: (text) {
                                print("Allowing to paste $text");
                                //if you return true then it will show the paste confirmation dialog. Otherwise if false, then nothing will happen.
                                //but you can show anything you want here, like your pop up saying wrong paste format or etc
                                return true;
                              },
                              appContext: context,
                            )),
                  Container(
                      width: MediaQuery.of(context).size.width * 0.9,
                      child: ListTile(
                        title: Text(
                          "Use [biometric]",
                          style: TextStyle(color: brandBlue, fontSize: 18),
                        ),
                        trailing: FlutterSwitch(
                          width: 70.0,
                          height: 30.0,
                          valueFontSize: 12.0,
                          toggleSize: 20.0,
                          value: biometricStatus,
                          activeText: "Yes",
                          activeTextColor: brandBlue,
                          inactiveText: "No",
                          activeColor: brandOrange,
                          borderRadius: 30.0,
                          padding: 8.0,
                          showOnOff: true,
                          onToggle: (val) {
                            setState(() {
                              biometricStatus = val;
                            });
                          },
                        ),
                      )),
                ],
              );
            }),
    

    And here is the code for the initial states

        TextEditingController textEditingController = TextEditingController();
    TextEditingController textEditingController2 = TextEditingController();
    StreamController<ErrorAnimationType> errorController;
    StreamController<ErrorAnimationType> errorController2;
    
    bool hasError = false;
    
    const brandBlue = const Color(0xff243665);
    const brandWhite = const Color(0xffF8F8FA);
    const brandLightGrey = const Color(0xffE7E9ED);
    const brandMediumGrey = const Color(0xffAAB0B9);
    const brandDarkGrey = const Color(0xff868E94);
    const brandLightBlue = const Color(0xff0FAFDA);
    const brandOrange = const Color(0xffEB684F);
    
    bool biometricStatus = true;
    
    String pincode1;
    String pincode2;
    var pinCodeType = 1;
    
    @override
    void initState() {
      errorController = StreamController<ErrorAnimationType>();
      textEditingController = TextEditingController();
      textEditingController2 = TextEditingController();
    
      pinCodeType = 1;
      super.initState();
    }
    
    @override
    void dispose() {
      errorController.close();
    
      super.dispose();
    }
    

    How do I get this right:?