完结篇—flutter的登录功能



csdn博客文章NO.2


前言:

          今天带来的是登录框业务处理的完结篇,看不懂的一定不要慌,一点一点的研究,做好个例拆分。看不明白的,不是你笨拙,而是有些地方你不知道是什么,可能见都没有见过,所有慢慢熟悉各个组件的功能。这将会成为你手中的武器。


提示:以下是本篇文章正文内容,下面案例可供手敲

一、首先输入手机号的表单要做到那几点?

  • 获得焦点的时候,表单的边框和右边的icon要变颜色
  • 限制输入,长度必须是11位,必须是整数值类型
  • 少位数提交不了,用提示框提示

第一点(这个框和密码框通用):
/*
 * WhitelistingTextInputFormatter.digitsOnly  //只允许输入数字
 * LengthLimitingTextInputFormatter(20) //限制长度
 */
  class MyInput extends StatefulWidget{
  //这几个是调整距离的
  double left;
  double right;
  double bottom;
  double top;
  double all;
  //输入框里面的提示文字
  String text;
  //icon图标
  IconData icon;
  //是否是密码框
  bool type;
  //一开始的颜色,也就是点击时的颜色
  Color initColor ;
  //是否一开始就获取焦点
  bool isFocus;
  //长度大于length才返回,11为手机号,那么length就要等于10
  int length;
  //限制用户输入的条件数组
  List<TextInputFormatter> inputFormatters;
  //回调函数
  ValueChanged<String> onChanged;
  MyInput({
    this.inputFormatters,
    this.all = 0,
    this.top = 0,
    this.bottom = 0,
    this.right = 28,
    this.left = 28,
    this.icon = Icons.check,
    this.text = "账号",
    this.type = false,
    this.onChanged,
    this.isFocus = false,
    this.length = 11,
    this.initColor,
  });

  State<StatefulWidget> createState() {
    return MyInputState();
  }
}

class  MyInputState extends State<MyInput>{
  //创建焦点
  FocusNode focusNode = FocusNode();
  //做个标记
  bool flag  = false;
  @override
  void initState() {
     //做个标记,这个输入框是和密码框通用的
     flag = widget.type;
     if(!widget.isFocus){
       widget.initColor =  Color(0xff5D5D62);
     }
     //焦点监听
    focusNode.addListener(() {
      //获得焦点
      if (focusNode.hasFocus) {
        setState(() {
          widget.initColor = MyColor.inputColor;
          print('获得焦点........');
        });
      }
      else {
          setState(() {
            widget.initColor = Color(0xff5D5D62);
            print('失去焦点........');
            //如果时密码框,失去焦点的时候要隐藏明文
            if(widget.type){
              setState(() {
                this.flag = true;
              });
            }
          });
      }
    },
    );
  }

  @override
  Widget build(BuildContext context) {
    return
      Container(
        padding: widget.all!=0?EdgeInsets.all(widget.all):EdgeInsets.fromLTRB(widget.left, widget.top, widget.right, widget.bottom),
        child: TextField(
          inputFormatters:widget.inputFormatters==null?[
            //默认允许输入字母数字一共11位数*
            WhitelistingTextInputFormatter(RegExp("[a-zA-Z]|[0-9.]")),
            LengthLimitingTextInputFormatter(11)
          ]:widget.inputFormatters,
          autofocus: widget.isFocus,//自动获取焦点
          focusNode: focusNode,//焦点监听
          obscureText:this.flag,//是否时密码框
          decoration: InputDecoration(
            filled: true,//设置背景颜色
            fillColor:MyColor.inputBcColor,
            hintText: widget.text,//文本
            border: InputBorder.none,//没有下划线
            focusedBorder: OutlineInputBorder(
              borderSide: BorderSide(
                //自定义的颜色
                color: MyColor.inputColor,
                width: 1.5,
              ),
            ),
            suffixIcon:
            IconButton(
              //右边显示的图标,SvgPicture是用来解析svg,比一些图片更灵活,然后是一个三元运算,结合密码框来的
              icon:flag?SvgPicture.asset("assets/eye.svg",color: widget.initColor):
              Icon(
                widget.icon,
                color: widget.initColor,
              ),
              onPressed: (){
                 //类型时密码框的时候点击才有效果
                 if(widget.type){
                   setState(() {
                     this.flag = !this.flag;
                   });
                 }
              },
            )
          ),
          //当输入手机号码的位数时才能返回
          onChanged: (value){
            if(value.toString().length > widget.minLength){
              widget.onChanged(value);
            }
          }
        ),
      );
  }
}




二、验证码的输入框(第一篇有讲怎么使用)

1.引入库

  //短信验证框
 //flutter_verification_box: ^1.0.4

2.短信验证框

 //短信验证功能
class VerificationCode extends StatelessWidget{
  //调整位置的
  double left;
  double right;
  double top;
  double bottom;
  //框的个数
  int count
  Function showCode = (String code){};


  VerificationCode({
    this.showCode,
    this.left = 0,
    this.right = 0,
    this.bottom = 0,
    this.top = 0
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom),
      decoration: BoxDecoration(
        color: MyColor.inputBcColor,
        borderRadius: BorderRadius.circular(4),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            margin: EdgeInsets.fromLTRB(ScreenUtil().setWidth(15), ScreenUtil().setHeight(20), 0, 20),
            child: Text(
              "手机验证码",style: TextStyle(fontSize: 16,fontWeight: FontWeight.w600,color:Color(0xff626F7A) ),
            ),
          ),
          Container(
            padding: EdgeInsets.only(left: 15,right: 15),
            height: ScreenUtil().setHeight(50),
            //这个被我改过源码,之前是要满足4个才返回,被修改之后是输入一个就返回一个
            child: VerificationBox(
              count: this.count,
              itemWidget:ScreenUtil().setHeight(50),
              showCursor: true,
              cursorColor: MyColor.inputColor,
              focusBorderColor: MyColor.inputColor,
              textStyle: TextStyle(fontSize: ScreenUtil().setSp(28),fontWeight: FontWeight.w600),
              onSubmitted: (code){
                showCode(code);
              },
            ),
          )
        ],
      ),
    );
  }
}

}


3.按钮

  • 验证码登录按钮比较特殊,一开始是灰色的,设置透明度
  • 有计时器,会一直减少
  • 输入框输入满了之后变成登录俩个字
  • 如果计数器倒数完毕,没有输入,就显示重新获取
样式:
//手机号
class HintMessage extends StatelessWidget{
  double top;
  String mobile;
  HintMessage({this.top,this.mobile});
  @override
  Widget build(BuildContext context) {
    return  Container(
      margin: EdgeInsets.only(top: this.top),
      child: Center(
        child: Text(
          "已发送验证码到${this.mobile}",
          style: TextStyle(
              fontSize: 14,
              color: MyColor.forbiddenColor
          ),
        ),
      ),
    );
  }


3.业务处理

  • 验证成功通过路由传参,把电话号码过来(实际工作中验证码不会直接传,要后台验证)

class VerificationPage extends StatefulWidget {
  //电话号码
  String mobile;
  //倒计时
  int countdownTime;
  VerificationPage({this.mobile,this.countdownTime});

  @override
  State<StatefulWidget> createState() {
    return VerificationPageState();
  }
}

class VerificationPageState extends State<VerificationPage>{

  double opacity = 0.5;
  String hint = "获取验证码";
  int timeOut = 0;
  Timer _timer;
  bool isFill = false;
  bool face = false;
  int initTime;
  @override
  void initState() {
   //计时器
    initTime = widget.countdownTime;
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        widget.countdownTime = widget.countdownTime - 1;
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      body: Container(
        child: ListView(
          children: [
            LoginTitle(),
            //填写完之后返回的验证码
            VerificationCode(
              top: ScreenUtil().setHeight(25),
              showCode: (code){
                 if(code.toString().length == 4){
                   Object pms = {"phone": widget.mobile, "code": code};
                   HttpController.fetch('xxxxxxxx', data: pms).then((result) {
                     if(result == "SUCCESS"){
                        face = true;
                     }
                   });
                   //输入完毕,登录按钮没有透明度,表示可以点击登录了
                   setState(() {
                     isFill = true;
                     opacity = 1;
                     hint = "登录";
                   });
                 }else{
                  //可以点击,不可以登录,重新获取验证码
                   setState(() {
                     isFill = false;
                     hint = "重新获取";
                   });
                 }
              },
            ),
            HintMessage(
                top: 30,
                mobile: widget.mobile,
            ),
            MyLoginButton(
                top: ScreenUtil().setHeight(30),
                text:widget.countdownTime >0&&!isFill ? '${widget.countdownTime}后重新获取' : hint,
                color: MyColor.inputColor,
                opacity: this.opacity,
                onTap: (){
                  if(isFill&&face){
                    //删除当前所有实例
                    RouteHelper.pushReplaceRoot( context, IndexPage());
                  }else if(isFill){
                    Fluttertoast.showToast(
                      msg: "验证码有误",
                      toastLength: Toast.LENGTH_LONG,
                      gravity: ToastGravity.TOP,
                      timeInSecForIosWeb: 1,
                      backgroundColor: Colors.red,
                      textColor: Colors.white,
                      fontSize: 16.0,
                    );
                  }
                    if(opacity == 1&& !isFill){
                    HttpController.fetch('/wx/sendBindCode', getpms: {'phone': widget.mobile}).then((data) {
                       setState(() {
                         widget.countdownTime = widget.countdownTime;
                       });
                    });
                  }
                },
            ),
          ],
        ),
      ),
      bottomNavigationBar: Permission(),
    );
  }
 }


总结

                有些地方会出错,其实这样更好,在你写的时候,可从这里找到你想要的
一些功能,我这里也仅仅是提供参考的作用。🤗🤗🤗🤗

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值