Flutter   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Flutter实战一Flutter聊天应用(十四)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

优化输入体验

在进行下一步之前,我们先优化一下注册的体验:

  • 正在输入注册信息时,点击屏幕空白部分,清除当前文本输入框的焦点,同时收起键盘
  • 正在输入注册信息时,直接收起键盘,再点击空白部分,清除当前文本输入框的焦点。
  • 不在用户输入时直接判断并显示错误提示信息,而是在用户输入完成以及点击加入按钮时判断并显示错误提示信息。
  • 在每一个输入框下方都显示帮助信息,提示用户输入什么内容
  • @H_450_17@

    首先我们把SignUpState类的_correctUsername_correctUsername变量改为bool类型。并把用户名和密码的判断逻辑合并到_checkInput方法中。

    class SignUpState extends State<SignUp> {
      bool _correctPhone = true;
      bool _correctUsername = true;
      bool _correctpassword = true;
      //...
      void _checkinput() {
        if (_phoneController.text.isnotEmpty &&
            (_phoneController.text.trim().length < 7 ||
                _phoneController.text.trim().length > 12)) {
          _correctPhone = false;
        } else {
          _correctPhone = true;
        }
        if (_usernameController.text.isnotEmpty &&
            _usernameController.text.trim().length < 2) {
          _correctUsername = false;
        } else {
          _correctUsername = true;
        }
        if (_passwordController.text.isnotEmpty &&
            _passwordController.text.trim().length < 6) {
          _correctpassword = false;
        } else {
          _correctpassword = true;
        }
        setState(() {});
      }
      //...
    }

    因为我们将使用手机号作为用户的唯一ID存储在数据库中,所以在上面的代码中,我们增加一个_correctPhone变量与判断手机号长度的逻辑。

    SignUpState类的build添加HelperText属性,它能在文本框下方显示输入帮助信息。使用onSubmitted代替onChanged属性,它会在用户点击键盘上的完成按钮时触发事件,也就是上面合并修改_checkInput方法

    class SignUpState extends State<SignUp> {
              //...
                          new TextField(
                            controller: _phoneController,keyboardType: TexTinputType.phone,decoration: new InputDecoration(
                              HelperText: 'Your unique ID.',hintText: 'Phone',errorText: _correctPhone
                                  ? null
                                  : 'phone length is 7 to 12 bits.',icon: new Icon(
                                Icons.phone,),onSubmitted: (value) {
                              _checkinput();
                            },new TextField(
                            controller: _usernameController,decoration: new InputDecoration(
                              HelperText: "what's your name?",hintText: 'Username',errorText: _correctUsername
                                  ? null
                                  : 'Username length is less than 2 bits.',icon: new Icon(
                                Icons.account_circle,new TextField(
                            controller: _passwordController,obscureText: true,keyboardType: TexTinputType.number,decoration: new InputDecoration(
                              HelperText: 'Your landing password.',hintText: 'password',errorText: _correctpassword
                                  ? null
                                  : 'password length is less than 6 bits.',icon: new Icon(
                                Icons.lock_outline,//...
    }

    然后我们需要在把有背景图片Container控件包装在GestureDetector控件中,再添加点击事件,清除文本输入框的焦点,然后判断输入内容

    class SignUpState extends State<SignUp> {
      //...
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            body: new Stack(children: <Widget>[
          new Opacity(
              opacity: 0.3,child: new GestureDetector(
                  onTap: () {
                    FocusScope.of(context).requestFocus(new Focusnode());
                    _checkinput();
                  },child: new Container(
                    decoration: new BoxDecoration(
                      image: new DecorationImage(
                        image: new ExactAssetImage('images/sign_up_BACkground.jpg'),fit: BoxFit.cover,))),//...
      }
      //...
    }

    最后我们在用户点击加入按钮提交注册信息之前,先清除文本输入框的焦点并判断输入内容

    class SignUpState extends State<SignUp> {
      //...
      Future _handleSubmitted() async {
        FocusScope.of(context).requestFocus(new Focusnode());
        _checkinput();
        //...
      }
      //...
    }

    添加等待动画

    用户在提交注册请求后,需要等待服务端返回请求结果,这一等待时间会根据当前网络的因素或长或短。所以我们现在要增加一个等待动画,使用CircularProgressInDicator控件实现,其效果一个不断转动的圆形。在等待期间我们不需要用户有其他操作,因此需一个新屏幕。

    class ShowAwait extends StatefulWidget {
      ShowAwait(this.requestCallBACk);
      final Future<int> requestCallBACk;
    
      @override
      _ShowAwaitState createState() => new _ShowAwaitState();
    }
    
    class _ShowAwaitState extends State<ShowAwait> {
      @override
      initState() {
        super.initState();
        new Timer(new Duration(seconds: 2),() {
          widget.requestCallBACk.then((int onvalue) {
            Navigator.of(context).pop(onvalue);
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new CircularProgressInDicator(),);
      }
    }

    上面代码中,在initState方法中有一个Timer类,它能设置定时任务,定时执行一次或者每隔一段时间执行一次,我们在这里设置的是定时2秒执行一次传入requestCallBAC方法。同时requestCallBAC方法需要返回一个int值,该值用于返回服务端的处理结果。执行完毕后使用Navigator.of(context).pop返回结果并关闭等待屏幕。

    提交注册信息

    然后回到sign_up.dart文件,我们要开始写服务端的代码,关于如何使用Firebase数据库,可以查看《Flutter进阶—Firebase数据库实例》,我们保存用户信息的数据名称users因此需要先连接上Firebase数据库

    class SignUpState extends State<SignUp> {
      //...
      final reference = FirebaseDatabase.instance.reference().child('users');
      //...
    }

    现在我们修改一下_userLogUp方法,在注册之前要先验证用户注册的手机号码是否已经存在,如果已经被注册,则返回0。确定当前手机号码未被注册之后,才提交用户注册信息到数据库并返1

    class SignUpState extends State<SignUp> {
      //...
      Future<int> _userLogUp(String username,String password,{String email,String phonE}) async {
        return await reference
            .child(_phoneController.text)
            .once()
            .then((DataSnapshot onvalue) {
          if (onValue.value == null) {
            reference.child(phonE).set({
              'name': username,'password': password,'email': email,'phone': phone,});
            return 1;
          } else {
            return 0;
          }
        });
      }
      //...
    }

    修改一下_handleSubmitted方法,在用户点击注册按钮时弹出ShowAwait创建的等待屏幕,并把上面的_userLogUp方法传给ShowAwait实例。如果返回0,则提示用户,如果返回1,则返回并传递用户的手机号、密码到登陆屏幕。

    class SignUpState extends State<SignUp> {
      //...
      void _handleSubmitted() {
        FocusScope.of(context).requestFocus(new Focusnode());
        _checkinput();
        if (_usernameController.text == '' || _passwordController.text == '') {
          showmessage(context,"The registration information is incomplete!");
          return;
        } else if (!_correctUsername || !_correctpassword || !_correctPhonE) {
          showmessage(context,"The registration information is incomplete!");
          return;
        }
        showDialog<int>(
            context: context,barrierDismissible: false,child: new ShowAwait(_userLogUp(
                _usernameController.text,_passwordController.text,email: _emailController.text,phone: _phoneController.text))).then((int onvalue) {
          if (onValue == 0) {
            showmessage(context,"This number has been registered!");
          } else if (onValue == 1) {
            Navigator
                .of(context)
                .pop([_phoneController.text,_passwordController.text]);
          }
        });
      }
      //...
    }

    Flutter实战一Flutter聊天应用(十四)

@H_313_404@

大佬总结

以上是大佬教程为你收集整理的Flutter实战一Flutter聊天应用(十四)全部内容,希望文章能够帮你解决Flutter实战一Flutter聊天应用(十四)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。