skip to Main Content

I want to set pin in PinFieldAutoFill using sms_autofill

I am facing 2 issues

1- setState() or markNeedsBuild() called during build.

2- Each child must be laid out exactly once.

Kindly let me know how to solve that issues.

Here is my code

class _SetPinScreenState extends State<SetPinScreen> {
  bool obscureText = true;
  TextEditingController _otpTextController = TextEditingController();
  bool isPinSet = false;
  String pin = '', confirmedPin = '';

  void _updatePin(String val) {
    if (pin.length != 4)
      pin = val;
    else
      confirmedPin = val;
    if (pin.length == 4) {
      setState(() {
        isPinSet = true;
      });
      
    }
  }

  @override
  void dispose() {
    _otpTextController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    bool isButtonEnabled = (pin == confirmedPin);
    return MainTemplate(
      isFloatingButtonVisible: true,
      isFloatingActionButtonDisabled: isButtonEnabled,
      floatingButtonAction: () {
        if (isButtonEnabled) {
          print("Floating action button pressed");
        }
      },
      child: Padding(
        padding: const EdgeInsets.all(15.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Align(
              alignment: Alignment.centerLeft,
              child: Text(
                isPinSet
                    ? 'Re-enter your PIN code to Confirm'
                    : 'Set PIN for your Card Ending With XXXX',
                style: TextStyle(fontWeight: FontWeight.w700, fontSize: 30),
              ),
            ),
            SizedBox(height: 20),
            Center(
              child: PinFieldAutoFill(
                decoration: UnderlineDecoration(
                  textStyle: Theme.of(context).textTheme.subtitle1.copyWith(
                        fontWeight: FontWeight.bold,
                        fontSize: 15,
                      ),
                  gapSpace: 8,
                  obscureStyle: ObscureStyle(isTextObscure: obscureText),
                  lineHeight: 1.2,
                  colorBuilder:
                      PinListenColorBuilder(Colors.black, Colors.grey.shade400),
                ),
                onCodeChanged: _updatePin,
                codeLength: 4,
               
                autoFocus: true,
                controller: _otpTextController,
                keyboardType: TextInputType.number,
              ),
            ),
            SizedBox(height: 20),
            Text(
              'Pin must be at least 4 digits. It must not be single digits like'
              ' 1111 or digits in numerical order such as 1234',
              style: TextStyle(
                color: Colors.black,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

2

Answers


  1. for your first issue, add your setState code into WidgetsBinding.instance.addPostFrameCallback block like below

      void _updatePin(String val) {
        if (pin.length != 4)
          pin = val;
        else
          confirmedPin = val;
        if (pin.length == 4) {
          WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
            setState(() {
              isPinSet = true;
            });
          })
        }
      }
    

    and for your second issue, i just found a post, might be helpful

    Update

    when i run your code, i finally found what the real issue is, in re-enter mod, the PinFieldAutoFill will be rebuilt every time you typed a number

      void _updatePin(String? val) {
        if (pin.length != 4)
          pin = val ?? '';
        else
          confirmedPin = val ?? '';
        if (pin.length == 4 && !isPinSet) {
          WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
            setState(() {
              isPinSet = true;
            });
          });
        }
      }  
    
    Login or Signup to reply.
  2. Try placing

    bool isButtonEnabled = (pin == confirmedPin);
    

    on onInit() function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search