flutter 发送验证码

一个发送验证码的需求:包括限制文本框输入长度和只允许输入数字

请使用===分割线===以下部分代码运行

按惯例 先上图: 

    

class MyBody extends StatefulWidget {
  @override
  _MyBodyState createState() => _MyBodyState();
}

class _MyBodyState extends State<MyBody> {
  bool  isButtonEnable=true;      //按钮状态  是否可点击
  String buttonText='发送验证码';   //初始文本
  int count=60;                     //初始倒计时时间
  Timer timer;                       //倒计时的计时器
  TextEditingController mController=TextEditingController();

  void _buttonClickListen(){
    setState(() {
      if(isButtonEnable){         //当按钮可点击时
        isButtonEnable=false;   //按钮状态标记
        _initTimer();

        return null;            //返回null按钮禁止点击
      }else{                    //当按钮不可点击时
//        debugPrint('false');
        return null;             //返回null按钮禁止点击
      }
    });
  }


 void _initTimer(){
    timer = new Timer.periodic(Duration(seconds: 1), (Timer timer) {
      count--;
      setState(() {
        if(count==0){
          timer.cancel();             //倒计时结束取消定时器
          isButtonEnable=true;        //按钮可点击
          count=60;                   //重置时间
          buttonText='发送验证码';     //重置按钮文本
        }else{
          buttonText='重新发送($count)';  //更新文本内容
        }
      });
    });
  }


  @override
  void dispose() {
    timer?.cancel();      //销毁计时器
    timer=null;
    mController?.dispose();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
//        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Container(
              color: Colors.white,
              padding: EdgeInsets.only(left: 10,right: 10),
              child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
//                  crossAxisAlignment: CrossAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.baseline,
                  textBaseline: TextBaseline.ideographic,
                  children: <Widget>[
                    Text('验证码',style: TextStyle(fontSize: 13,color: Color(0xff333333)),),
                    Expanded(
                      child: Padding(padding: EdgeInsets.only(left: 15,right: 15,top: 15),
                      child: TextFormField(
                        maxLines: 1,
                        onSaved: (value) { },
                        controller: mController,
                        textAlign: TextAlign.left,
                        inputFormatters: [WhitelistingTextInputFormatter.digitsOnly,LengthLimitingTextInputFormatter(6)],
                        decoration: InputDecoration(
                          hintText: ('填写验证码'),
                          contentPadding: EdgeInsets.only(top: -5,bottom: 0),
                          hintStyle: TextStyle(
                            color: Color(0xff999999),
                            fontSize: 13,
                          ),
                          alignLabelWithHint: true,
                          border: OutlineInputBorder(borderSide: BorderSide.none),
                        ),
                      ),),
                    ),
                    Container(
                      width: 120,
                      child: FlatButton(
                        disabledColor: Colors.grey.withOpacity(0.1),     //按钮禁用时的颜色
                        disabledTextColor: Colors.white,                   //按钮禁用时的文本颜色
                        textColor:isButtonEnable?Colors.white:Colors.black.withOpacity(0.2),                           //文本颜色
                        color: isButtonEnable?Color(0xff44c5fe):Colors.grey.withOpacity(0.1),                          //按钮的颜色
                        splashColor: isButtonEnable?Colors.white.withOpacity(0.1):Colors.transparent,
                        shape: StadiumBorder(side: BorderSide.none),
                        onPressed: (){ setState(() {
                          _buttonClickListen();
                        });},
//                        child: Text('重新发送 (${secondSy})'),
                        child: Text('$buttonText',style: TextStyle(fontSize: 13,),),
                      ),
                    ),
                  ],
              ),
          ),
          Container(
            width: double.infinity,
            height: 45,
            margin: EdgeInsets.only(top: 50,left: 10,right: 10),
            child: RaisedButton(
              onPressed: () {
                debugPrint('${mController.text}');
              },
              shape: StadiumBorder(side: BorderSide.none),
              color: Color(0xff44c5fe),
              child: Text(
                '下一步',
                style: TextStyle(color: Colors.white,fontSize: 15),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

=============================分割线===============================

鉴于部分朋友评论不知道怎么用 其实就当成一个小组件就可以了  至于代码有报错  我这里解释一下,这篇文章是比较早的,当时还没有空安全的检测  而且 我很久没写flutter了  但是为了解决各位的问题  我重新写了一下这个demo,下面把代码贴出来

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class msgcode extends StatefulWidget {
  const msgcode({Key? key}) : super(key: key);

  @override
  State<msgcode> createState() => _MsgCodeState();
}

class _MsgCodeState extends State<msgcode> {
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
        appBar:AppBar(
          automaticallyImplyLeading: true,
          title:const Text('验证码倒计时小组件'),
        ),
        body: const MyBody(),
    );
  }
}

class MyBody extends StatefulWidget {
  const MyBody({Key? key}) : super(key: key);

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

class _MyBodyState extends State<MyBody> {
  bool isButtonEnable=true;      //按钮初始状态  是否可点击
  String buttonText='发送验证码';   //初始文本
  int count=60;                     //初始倒计时时间
  Timer? timer;                       //倒计时的计时器
  TextEditingController? mController=TextEditingController();


  
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
//        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Container(
            alignment: Alignment.center,
            padding: const EdgeInsets.only(left: 10,right: 10,top: 10),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.center,
              textBaseline: TextBaseline.ideographic,
              children: <Widget>[
                const Text('验证码',style: TextStyle(fontSize: 13,color: Color(0xff333333))),
                Expanded(
                  child: Padding(padding: const EdgeInsets.only(left: 15,right: 15),
                    child: TextFormField(
                      maxLines: 1,
                      onSaved: (value) { },
                      controller: mController,
                      textAlign: TextAlign.start,
                       inputFormatters: [
                        FilteringTextInputFormatter.allow(RegExp("[0-9]")),    //只允许输入0-9的数字
                        LengthLimitingTextInputFormatter(6)                     //最大输入长度为6
                      ],
                      decoration: const InputDecoration(
                        hintText: ('填写验证码'),
                        // fillColor: Colors.red,  //设置TextFormField背景颜色
                        // filled: true,
                        contentPadding: EdgeInsets.only(top: 25,bottom: 0),
                        hintStyle: TextStyle(
                          color: Color(0xff999999),
                          fontSize: 13,
                        ),
                        alignLabelWithHint: true,

                        border: OutlineInputBorder(borderSide: BorderSide.none),
                      ),
                    ),),
                ),
                 SizedBox(
                  width: 120,
                  child: FlatButton(
                    disabledColor: Colors.grey.withOpacity(0.1),     //按钮禁用时的颜色
                    disabledTextColor: Colors.white,                   //按钮禁用时的文本颜色
                    textColor:isButtonEnable?Colors.white:Colors.black.withOpacity(0.2),                           //文本颜色
                    color: isButtonEnable?const Color(0xff44c5fe):Colors.grey.withOpacity(0.1),                          //按钮的颜色
                    splashColor: isButtonEnable?Colors.white.withOpacity(0.1):Colors.transparent,
                    shape:const StadiumBorder(side: BorderSide.none),
                    onPressed: (){
                      if(isButtonEnable){
                        debugPrint('$isButtonEnable');
                        setState(() {
                          _buttonClickListen();
                        });
                      }},
                    child:Text(buttonText,style:const TextStyle(fontSize: 13,),),
                  ),
                ),
              ],
            ),
          ),
          Container(
            width: double.infinity,
            height: 45,
            margin: const EdgeInsets.only(top: 50,left: 10,right: 10),
            child: ElevatedButton(
              onPressed: () {
                debugPrint('${mController?.text}');
              },
              style: ButtonStyle(
                backgroundColor:MaterialStateProperty.all(const Color(0xff44c5fe)),
                shape: MaterialStateProperty.all(const StadiumBorder(side: BorderSide.none)),//圆角弧度
              ),

              child:const Text('下一步', style: TextStyle(color: Colors.white,fontSize: 15),
              ),
            ),
          ),
        ],
      ),
    );
  }


  void _buttonClickListen(){
    setState(() {
      if(isButtonEnable){         //当按钮可点击时
        isButtonEnable=false;   //按钮状态标记
        _initTimer();
      }
    });
  }

  void _initTimer(){
    timer = Timer.periodic(const Duration(seconds: 1), (Timer timer) {
      count--;
      setState(() {
        if(count==0){
          timer.cancel();             //倒计时结束取消定时器
          isButtonEnable=true;        //按钮可点击
          count=60;                   //重置时间
          buttonText='发送验证码';     //重置按钮文本
        }else{
          buttonText='重新发送($count)';  //更新文本内容
        }
      });
    });
  }

  @override
  void dispose() {
    timer?.cancel();      //销毁计时器
    timer=null;
    mController?.dispose();
    super.dispose();
  }

}

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Flutter 中实现验证码倒计时可以通过使用计时器 Timer 来实现。以下是一个简单的示例: 1. 首先定义一个变量 `countdownTime` 表示倒计时的时间,以秒为单位。 ```dart int countdownTime = 60; ``` 2. 然后定义一个变量 `timer` 来控制计时器的执行。 ```dart Timer timer; ``` 3. 在需要开始倒计时的时候,启动计时器,并在计时器中更新倒计时的时间。 ```dart void startCountdown() { timer = Timer.periodic(Duration(seconds: 1), (timer) { setState(() { if (countdownTime < 1) { timer.cancel(); } else { countdownTime -= 1; } }); }); } ``` 4. 在界面中显示倒计时的时间。可以使用 Text 组件来显示,然后在组件的 text 属性中使用字符串插值来显示倒计时的时间。 ```dart Text('倒计时 $countdownTime 秒') ``` 完整的示例代码如下: ```dart import 'dart:async'; import 'package:flutter/material.dart'; class CountdownPage extends StatefulWidget { @override _CountdownPageState createState() => _CountdownPageState(); } class _CountdownPageState extends State<CountdownPage> { int countdownTime = 60; Timer timer; void startCountdown() { timer = Timer.periodic(Duration(seconds: 1), (timer) { setState(() { if (countdownTime < 1) { timer.cancel(); } else { countdownTime -= 1; } }); }); } @override void dispose() { timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('验证码倒计时'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('倒计时 $countdownTime 秒'), SizedBox(height: 16), RaisedButton( child: Text('开始倒计时'), onPressed: startCountdown, ), ], ), ), ); } } ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值