我想在没有任何包的情况下实现 OTP 验证屏幕

I want to implement OTP verification screen without any package

我想在没有任何包的情况下实现 OTP 验证屏幕。 当我输入数字时,它应该移动到下一个输入字段

当输入数据的长度达到一时,您将不得不更改文本字段焦点节点。
例如
如果您在第一个字段中,并且输入了一个数字字段,那么一个焦点应该丢失,而第二个字段应该是焦点。这可以通过 requestFocus 来完成。

本文将为您提供帮助:Flutter Focus

我在当前项目中使用此代码作为参考,这将有所帮助

class Otp extends StatefulWidget {
 final String?  phnNumber;
  final String ? code;
  String?  from;
   Otp({Key ?key, this.phnNumber, this.from, this.code}) : super(key: 
   key);

      @override
     _OtpState createState() => _OtpState();
      }

  class _OtpState extends State<Otp> {
    double  ? height ;
    double ? width;
    TextEditingController ? contrller1;
     TextEditingController ? contrller2;
    TextEditingController ? contrller3;
    TextEditingController ? contrller4;
      SendOtpRequest resend = SendOtpRequest();
     SharedPreferences ? prefs;
    getSharedPreferences () async
        {
     prefs = await SharedPreferences.getInstance();
     }
   String  Code  = "";
   @override
  void initState() {
   // TODO: implement initState
    super.initState();
   contrller1 = TextEditingController();
     contrller2 = TextEditingController();
     contrller3 = TextEditingController();
   contrller4 = TextEditingController();
     getSharedPreferences();
     }
   @override
    Widget build(BuildContext context) {
    height= MediaQuery.of(context).size.height;
   width = MediaQuery.of(context).size.height;
   final verifyprovider = Provider.of<PostDataProvider>(context);
    return Scaffold(
    resizeToAvoidBottomInset: false,
       appBar: AppBar(
        toolbarHeight:height! * 0.07802345,
         titleSpacing: 0,
          backgroundColor: HexColor("#18263d"),
          automaticallyImplyLeading: false,
          leading:   Padding(
           padding: const EdgeInsets.only(left: 8.0,),
           child: GestureDetector(
            onTap: () {
              Navigator.pop(context);
              },
              child: Container(
              color: Colors.transparent,
              child: Image.asset("assets/images/back_ic-1.png")),
              ),
              ),
            // SizedBox(width: width!*0.001234,),
            title:Row(
             mainAxisAlignment: MainAxisAlignment.start,
            children: [
             Container(
             height: height!/15,
              width: height!/15,
               decoration: BoxDecoration(
                shape: BoxShape.circle,
                border: Border.all(
                  width: 2,
                  color:HexColor("#fc4f00"),
                     )),
                  child: Padding(
                   padding: const EdgeInsets.all(1.0),
                  child: Container(
                   height: height!/11,
                   width: height!/11,
                    decoration: BoxDecoration(
                      image: const DecorationImage(
                           image: 
                      AssetImage("assets/images/home_logo.png"),
                        fit: BoxFit.fill
                    ),
                    shape: BoxShape.circle,
                    border: Border.all(
                      width: 1,
                      color:HexColor("#fc4f00"),
                    )),
              ),
            ),
          ),
          SizedBox(width: width! * 0.04234,),
          Padding(
            padding: const EdgeInsets.only(bottom: 8.0),
            child: Text("Verification",
              style: GoogleFonts.oswald(fontWeight: FontWeight.bold,
                  color: Colors.white,
                  fontSize: width! * 0.03345
              ),),
          ),
        ],
      ) ,
    ),
  body: SafeArea(
    child: Padding(
      padding: EdgeInsets.symmetric(vertical: 24, horizontal: 32),
      child: Column(
        children: [
          Text("We have send verification code on your mobile number",
            style: GoogleFonts.oswald(fontStyle: FontStyle.normal,
                fontSize: width!*0.0234,
                color: HexColor("#8b8b8b")),
          ),
          SizedBox(height: height!/38,),
          Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  _textFieldOTP(first: true, last: false,controllerr: 
                    contrller1),
                  _textFieldOTP(first: false, last: false,controllerr: 
                    contrller2),
                  _textFieldOTP(first: false, last: false,controllerr: 
                contrller3),
                  _textFieldOTP(first: false, last: true, controllerr: 
                  contrller4),
                ],
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: InkWell(
                  onTap:() {
                   resend.phoneNumber= widget.phnNumber;
                   resend.countryCode = widget.code;
                   verifyprovider.resendOtp(context, 
                 jsonEncode(resend));
                  },
                  child: Text("Resend OTP?",
                    style: GoogleFonts.oswald(fontStyle: 
                        FontStyle.normal,
                        fontSize: width!*0.0234,
                        color: HexColor("#fc4f00")),
                  ),
                ),
              ),

              SizedBox(height: height!/28,),
              GestureDetector(
                onTap: (){
                  if(contrller1!.text.isNotEmpty&& 
                 contrller2!.text.isNotEmpty&&contrller3!.
             text.isNotEmpty&&contrller4!.text.isNotEmpty){
                    verifyOtpRequest verify = verifyOtpRequest();
                    verify.phoneNumber = widget.phnNumber;
                    verify.otp= 
                   contrller1!.text+contrller2!.
                  text+contrller3!.text+contrller4!.text;
                    verifyprovider.otpVerification(context, 
                  jsonEncode(verify), widget.from);
                  }else{
                    CommonUtils.showToast(msg: "Please fill all the 
                  fields ");
                  }

                },
                child: Container(
                    height: height!/18,
                    width: width,
                    decoration: BoxDecoration(
                        color: HexColor("#fc4f00"),
                        borderRadius: BorderRadius.circular(10)
                    ),
                    child: Center(
                      child: Text("Verify",style: TextStyle(
                          color: Colors.white,
                          fontSize: width!*0.02345
                      ),),
                      )
                    ),
              ),
                ],
              ),
              ],
              ),
            ),
             ),
             );
           }

       Widget _textFieldOTP({bool ? first, last, 
       TextEditingController ? 
       controllerr}) {
return Container(
  height:height!/12 ,
  child: AspectRatio(
    aspectRatio: 1.0,
    child: TextField(
      controller: controllerr,
      autofocus: true,
      onChanged: (value) {
        if (value.length == 1 && last == false) {
          FocusScope.of(context).nextFocus();
        }
        if (value.length == 0 && first == false) {
          FocusScope.of(context).previousFocus();
        }
      },
      showCursor: false,
      readOnly: false,
      textAlign: TextAlign.center,
      style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
      keyboardType: TextInputType.number,
      maxLength: 1,
      decoration: InputDecoration(
        counter: Offstage(),
        enabledBorder: OutlineInputBorder(
            borderSide: BorderSide(width: 2, color: Colors.black54),
            borderRadius: BorderRadius.circular(12)),
        focusedBorder: OutlineInputBorder(
            borderSide: BorderSide(width: 2, color: Colors.black54),
            borderRadius: BorderRadius.circular(12)),
      ),
    ),
  ),
);

} }