Flutter how to clean this input field for pincode

4.1k views Asked by At

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:?

1

There are 1 answers

0
Omatt On

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.