Flutter学习笔记(二)登陆注册界面的实现

Flutter学习笔记(二)登陆注册界面的实现

    • 简单的登录和注册界面的布局
    • SharedPreferences存储数据
    • 页面路由和参数传递的心得

这几天按照顺序先完成了登录和注册的页面,没有什么特别的东西,就是异步这个东西之前只有在用JS做前端的时候遇到了一次问题,还是同学帮忙解决的,这一次又遇到了所以多花了一点时间debug。

简单的登录和注册界面的布局

由于是刚刚开始学习flutter,于是就偷懒参考了现成的布局设计和代码,自己修改了一番。
效果如图所示,参考自用flutter写一个精美的登录页面,暂时没有做页面适配,以后学习到了会补上。
Flutter学习笔记(二)登陆注册界面的实现_第1张图片
Flutter学习笔记(二)登陆注册界面的实现_第2张图片
布局的代码参考上面引用的教程,这里主要说一下由于登录和注册都是在按钮onPressed之后才触发判断TextFormField中的值,所以使用了全局的GlobalKey来验证输入是否符合要求,但是这样有一个问题,那就是在判断输入符合要求之后在保存,那么在判断确认密码的时候还没有获取到第一次输入密码的值,于是就使用了TextEditingController来获取输入的值。在onPressed之后,调用_userRegister()方法获取值并进行判断。

代码如下:

  
  TextEditingController _controllerMail = new TextEditingController();
  TextEditingController _controllerPwd = new TextEditingController();
  TextEditingController _controllerRePwd = new TextEditingController();
  
  void _userRegister() {
      _email=_controllerMail.text;
      _password=_controllerPwd.text;
      _password_confirm=_controllerRePwd.text;

      if (_formKey.currentState.validate()) {
        save();//使用sharedPreferences存储数据
        Navigator.pop(context);//返回到登陆页面
      }
  }

SharedPreferences存储数据

由于暂时只是应用前端部分,没有后台服务器和数据库,所以暂时用shared_preferences暂时存储注册的账户和密码,由于数据存储都是耗时进程,所以都要用到async/await来执行。

注册界面的存储数据代码:

save() async{
    final prefs = await SharedPreferences.getInstance();
    prefs.setString(_email,_password);//存数据
  }

登陆界面的取数据代码:

getPwd(String userEmail) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _passwordRe=prefs.get(userEmail);//取数据
    await check(_password,_passwordRe);//判断密码是否正确
    await login();//登陆操作
  }

其他关于SharedPreferences详细操作可以参看Flutter数据存储之shared_preferences,总结的挺不错的。

在写登录页面时遇到了一点小麻烦,第一次输入密码无论正确与否总时被判断为错误,后来发现又是由于异步操作的问题,因为从SharedPreferences实例中取数据的操作耗时较长,导致先判断之后,变量才被赋值。于是将判断和登录的操作放进await里,问题得到了解决。

页面路由和参数传递的心得

第三个问题就是涉及到页面的跳转和参数的传递了。首先我要实现的是,第一次启动App时进入的是登录页面,如果没有账号则点击注册,进入注册界面。原本我认为只是一个简单的Navigator.push()的方法,但是事实上要稍微复杂一点。例如我从登录界面点击注册到达了注册界面,并且在注册界面完成了注册,点击注册按钮之后,如果直接进入主页,显然不太符合精神模型。一般会返回到登录页面并且已经保存好了用户名,等待输入密码后登录。这才是比较合适的设计。但是如果我点击注册按钮触发的是一个push()操作,那么我们会进入一个新的登录页面,即语句new Login Page(),这种情况下,我再点击返回按钮则会经历 “登录界面” => “注册界面” => “登陆界面” =>退出程序。这样似乎也不太合适,所以注册按钮触发的应该是Navigator.pop() 才对。
但是我查了很久才找到接收pop方法参数的例子,相比于接收push参数要相对复杂一点。具体的做法是将跳转语句放入await中,通过一个Future对象获得返回参数的值。

代码如下:

//构建注册按钮
Align buildRegisterText(BuildContext context) {
    return Align(
      alignment: Alignment.center,
      child: Padding(
        padding: EdgeInsets.only(top: 10.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('没有账号?'),
            GestureDetector(
              child: Text(
                '点击注册',
                style: TextStyle(color: Colors.green),
              ),
              onTap: () {
                _toRegisterPage(context);//跳转注册页面方法。
              },
            ),
          ],
        ),
      ),
    );
  }

  _toRegisterPage(BuildContext context) async{
      final preEmail = await Navigator.push(
          context,
          new MaterialPageRoute(
              builder: (context) => new RegisterPage()));
      _email=new Text("$preEmail").data;//接收传递的参数
      _email = _email.substring(1,_email.length-1);//处理为已注册的用户邮箱
  }
  

注册界面pop传递参数相对简单,代码如下:


Navigator.pop(context,[_email]);//传递用户邮箱

登陆界面对于邮箱输入框的构造也要加以改动,代码如下:

TextFormField buildEmailTextField() {
    return TextFormField(
      decoration: InputDecoration(
        labelText: 'Email Address',
      ),
      controller: TextEditingController.fromValue(
        TextEditingValue(
            text: _email//填入预先存储的邮箱
        )
    ),
    ......
  }

到这里,简单的登录注册界面就算是完成了,后期会对屏幕适配和布局进行优化和改动,并且有空会实现记住已登录用户并且选择账号登录的功能,加入网络请求之后也会进行改动和添加。

参考资料:

  • 用flutter写一个精美的登录页面
  • Flutter数据存储之shared_preferences
  • flutter入门之实现登陆页面的记住历史登录账号功能
  • 从新页面返回数据给上一个页面

你可能感兴趣的:(flutter学习笔记)