-1

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,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
For Stack
  • 165
  • 15

3 Answers3

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;
        });
      });
    }
  }  
Zhentao
  • 344
  • 7
  • i write like this but when i enter digit it change the screen to text `Re-enter your PIN code to Confirm` and here i can't type digit. – For Stack Aug 10 '23 at 06:03
  • It resolve the second issue also. – For Stack Aug 10 '23 at 06:07
  • but when i want to re-type my code it is not typing on `PinFieldAutoFill` – For Stack Aug 10 '23 at 06:08
  • @ForStack i just updated my answer, try that code and see if it works – Zhentao Aug 10 '23 at 06:18
  • NO, It is not allowing me to type . – For Stack Aug 10 '23 at 06:27
  • 1
    @ForStack i really found what the issue is, try the newest code, defiantly works – Zhentao Aug 10 '23 at 06:38
  • It works bro, Thanks, but it lose the focus, I have to click on field again to re-enter otp so how to auto focus as it before. – For Stack Aug 10 '23 at 07:12
  • lose the focus? i have no idea with that, in my demo code i replace `MainTemplate` with `Container` to make the code be runnable, you may need to find it out by your self@ForStack – Zhentao Aug 10 '23 at 07:31
  • Hi, kindly answer of that question [https://stackoverflow.com/questions/76878982/how-to-clear-first-text-controller-flutter](https://stackoverflow.com/questions/76878982/how-to-clear-first-text-controller-flutter) – For Stack Aug 10 '23 at 21:20
  • bro, i need some help kindly response on this message – For Stack Aug 14 '23 at 09:33
  • @ForStack it's been two days and you still haven't solved your issue? sorry bro, i can't help you, i have a lot of shit to do – Zhentao Aug 15 '23 at 02:16
  • or you can post another question contains all your issues, i will take a look if i am free – Zhentao Aug 15 '23 at 02:18
  • kindly take a look on [https://stackoverflow.com/questions/76902139/flutter-how-to-hide-and-show-floatingbutton#76902249](https://stackoverflow.com/questions/76902139/flutter-how-to-hide-and-show-floatingbutton#76902249) – For Stack Aug 15 '23 at 03:59
  • after setting my PIN my screen switch to Re-enter your PIN code to Confirm screen and here my PinFieldAutoFill is not accepting input after editing given answer. – For Stack Aug 15 '23 at 04:00
0

Try placing

bool isButtonEnabled = (pin == confirmedPin);

on onInit() function.

Kyoto
  • 308
  • 4
  • 4
0

Before call setState({}) method check widget mounted


if(mounted) {
   setState(() {
     isPinSet = true;
   });
}
Jenish MS
  • 357
  • 2
  • 13