美文网首页futter学习
Flutter:一份无瑕疵的登录页代码

Flutter:一份无瑕疵的登录页代码

作者: dvlproad | 来源:发表于2019-03-09 11:29 被阅读0次

    最终实现的效果及需要实现的内容,如下图所示:

    用户名登录的UI图.png

    用户名登录的流程图如下:

    用户名登录的流程图.png

    包含内容:

    • 文本框定制
    • 文本框焦点问题
    • 键盘问题

    相应的代码如下:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'dart:async';
    import 'dart:ui';
    import 'package:cj_flutter_logindemo/CommonUI/CommonUIFactory.dart';
    import 'package:cj_flutter_logindemo/CommonUI/ButtonFactory.dart';
    import 'package:cj_flutter_logindemo/CommonUI/TextFieldFactory.dart';
    import 'package:cj_flutter_logindemo/Util/ChannelUtil.dart';
    import 'package:cj_flutter_logindemo/Service/Channel/NativeCallChannelModel.dart';
    import 'ForgetPassword.dart';
    
    class MyLoginPage extends StatefulWidget {
      MyLoginPage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyLoginPageState createState() => _MyLoginPageState();
    }
    
    class _MyLoginPageState extends State<MyLoginPage> {
      bool userNameValid = false;
      bool passwordValid = false;
      bool loginValid = false;
      bool passwordClearValid = false;
      bool shouldAutofocusUserNameTextField = false;
      String userName = "";
      String password = "";
    
      //定义一个controller
      TextEditingController _usernameController = new TextEditingController();
      TextEditingController _passwordController = new TextEditingController();
      FocusNode usernameFocusNode = new FocusNode();
      FocusNode passwordFocusNode = new FocusNode();
      FocusScopeNode currentFocusNode;
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        print("Login Page initState");
    
        //eventChannel.receiveBroadcastStream("UserNameAutofocus").listen(_onLisentEventAutofocus, onError: _onErrorAutofocus);
    
        //监听文本变化方式②设置controller并实现监听
        _usernameController.addListener(() {
          userName = _usernameController.text;
          print("listen username:" + _usernameController.text);
          _updateAllViewState();
        });
    
        _passwordController.addListener(() {
          password = _passwordController.text;
          print("listen password:" + _passwordController.text);
          _updateAllViewState();
        });
    
        _getDefaultLoginAccountAction();
      }
    
      @override
      void didChangeDependencies() {
        // TODO: implement didChangeDependencies
        super.didChangeDependencies();
    
        print("Login Page didChangeDependencies");
      }
    
      @override
      void didUpdateWidget(MyLoginPage oldWidget) {
        // TODO: implement didUpdateWidget
        super.didUpdateWidget(oldWidget);
    
        print("Login Page didUpdateWidget");
      }
    
      void _onLisentEventAutofocus(Object event) {
        print("_onLisentEventAutofocus:" + event);
        _updateAutofocus(event);
      }
    
      void _onErrorAutofocus(Object error) {
        setState(() {});
      }
    
    
      // 更新文本框的聚焦
      void _updateAutofocus(dynamic userNameAutofocusValue) {
        String userNameAutofocusString;
        if (userNameAutofocusValue is bool) {
          //原生返回bool值时候调用的方法
          bool userNameAutofocus = userNameAutofocusValue as bool;
          shouldAutofocusUserNameTextField = userNameAutofocus;
          userNameAutofocusString = shouldAutofocusUserNameTextField ? "YES" : "NO";
          print("2.bool userNameAutofocusString:" + userNameAutofocusString);
        } else {
          //原生返回String值时候调用的方法
          userNameAutofocusString = userNameAutofocusValue as String;
          shouldAutofocusUserNameTextField = userNameAutofocusString == "YES";
          print("1.String userNameAutofocusString:" + userNameAutofocusString);
        }
    
        setState(() {
          //_usernameController.text = userNameAutofocusString;
          if (shouldAutofocusUserNameTextField) {
            if (null == currentFocusNode) {
              currentFocusNode = FocusScope.of(context);
            }
            currentFocusNode.requestFocus(usernameFocusNode);
          } else {
            usernameFocusNode.unfocus();
            passwordFocusNode.unfocus();
          }
        });
      }
    
    
      void _updateAllViewState() {
        userNameValid = userName.length > 0;
        passwordValid = password.length > 6 && password.length < 50;
        loginValid = userNameValid && passwordValid;
        passwordClearValid = password.length > 0;
        setState(() {});
      }
    
      _getDefaultLoginAccountAction() {
        try {
          userName = "Beyond";
          password = "";
          print(userName + ":" + password);
    
          setState(() {
            _usernameController.text = userName;
            _passwordController.text = password;
          });
        } on PlatformException {}
      }
    
      _login() async {
        try {
    //      Map<String, dynamic> flutterParams = {
    //        "userName": userName,
    //        "password": password
    //      };
    //      await callNativeMethodChannel.invokeMethod('login', callNativeFlutterParams(flutterParams));
        } on PlatformException {}
      }
    
      _goForgetPasswordViewController() {
        try {
    //      Map<String, dynamic> flutterParams = {
    //        "userName": userName,
    //        "password": password
    //      };
    //      await callNativeMethodChannel.invokeMethod('goForgetPasswordViewController', callNativeFlutterParams(flutterParams));
          ForgetPasswordRoute();
        } on PlatformException {}
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            alignment: Alignment.center, //指定未定位或部分定位widget的对齐方式
            children: <Widget>[
              GestureDetector(
                behavior: HitTestBehavior.translucent,
                onTap: () {
                  FocusScope.of(context).requestFocus(new FocusNode());
                },
                child: ListView(
                  children: loginWidgets(),
                ),
              ),
            ],
          ),
        );
      }
    
      // 登录页视图
      List<Widget> loginWidgets() {
        MediaQueryData mediaQuery = MediaQuery.of(context);
        double screenHeight = mediaQuery.size.height;
        //print("screenHeight = " + screenHeight.toString());
        double loginIconTop = screenHeight <= 667 ? 80 : 106;
        double loginIconBottom = screenHeight <= 667 ? 50 : 71;
        return <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(top: loginIconTop),
                child: loginIconImage(),
              ),
            ],
          ),
          Padding(
            padding: EdgeInsets.only(top: loginIconBottom, left: 25, right: 25),
            child: userNameTextField2(),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 20, left: 25, right: 25),
            child: passwordTextField(),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(top: 15, right: 25),
                child: forgetPassword(),
              ),
            ],
          ),
          Padding(
            padding: const EdgeInsets.only(top: 15, left: 25, right: 25),
            child: Flex(
              direction: Axis.horizontal,
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: loginButton(),
                ),
              ],
            ),
          ),
        ];
      }
    
      // 登录页Icon
      Image loginIconImage() {
        return Image(
            image: AssetImage(
                "lib/Resources/login/login_icon.png"),
            width: 113.0,
            height: 113.0);
      }
    
    
    
      // 用户名文本框
      LoginTextField userNameTextField2() {
        return LoginTextField(
            placeholder: "用户名",
            prefixIconImageName: userNameValid
                ? 'lib/Resources/login/login_username_blue.png'
                : 'lib/Resources/login/login_username_gray.png',
            autofocus: shouldAutofocusUserNameTextField,
            keyboardType: TextInputType.text,
            controller: _usernameController,
            textInputAction: TextInputAction.next,
            focusNode: usernameFocusNode, //usernameFocusNode
            onSubmitted: (text) {
              print("current userName:" + text);
              if (null == currentFocusNode) {
                currentFocusNode = FocusScope.of(context);
              }
              currentFocusNode.requestFocus(passwordFocusNode);
            }
        );
      }
    
      TextField userNameTextField() {
        return  TextField(
            autofocus: shouldAutofocusUserNameTextField,
            style: TextStyle(color: Colors.black, fontSize: 17.0),
            decoration: InputDecoration(
              contentPadding: EdgeInsets.all(0.0),
              //labelText: "用户名",
              hintText: "用户名",
              //prefixIcon: Icon(Icons.person),
              prefixIcon: new Image.asset(
                userNameValid ? 'lib/Resources/login/login_username_blue.png' : 'lib/Resources/login/login_username_gray.png',
                width: 14.0,
                height: 15.0,
              ),
              enabledBorder: loginTextFieldDecorationBorder(),
              focusedBorder: loginTextFieldDecorationBorder(),
            ),
            keyboardType: TextInputType.text,
            controller: _usernameController,
            textInputAction: TextInputAction.next,
            focusNode: usernameFocusNode, //usernameFocusNode
            onSubmitted: (text) {
              print("current userName:" + text);
              if (null == currentFocusNode) {
                currentFocusNode = FocusScope.of(context);
              }
              currentFocusNode.requestFocus(passwordFocusNode);
            }
            );
      }
    
      // 密码文本框
      TextField passwordTextField() {
        return TextField(
            controller:
            _passwordController, //监听文本变化方式②设置controller并实现监听
            decoration: InputDecoration(
              contentPadding: EdgeInsets.all(0.0),
              //labelText: "密码",
              hintText: "密码",
              //prefixIcon: Icon(Icons.lock),
              prefixIcon: new Image.asset(
                passwordValid ? 'lib/Resources/login/login_password_blue.png' : 'lib/Resources/login/login_password_gray.png',
                width: 14.0,
                height: 15.0,
              ),
              suffixIcon: !passwordClearValid ? null : clearButtonWithOnPressed(_passwordController.clear),
              enabledBorder: loginTextFieldDecorationBorder(),
              focusedBorder: loginTextFieldDecorationBorder(),
            ),
            obscureText: true, //是否隐藏正在编辑的文本
            textInputAction: TextInputAction.done,
            focusNode: passwordFocusNode,
            onSubmitted: (text) {
              print("current password:" + text);
              passwordFocusNode.unfocus();
              if(loginValid){
                _login();
              }
            });
      }
    
    
      // 忘记密码按钮
      FlatButton forgetPassword() {
        return FlatButton(
          child: Text("忘记密码?"),
          textColor: Color(0xfff5b63c),
          onPressed: () {
            _goForgetPasswordViewController();
          },
        );
      }
    
      // 登录按钮
      FlatButton loginButton() {
        return BlueButton2(
          text: "登录",
          enable: loginValid,
          enableOnPressed: _login
          );
        //return blueButton("登录", loginValid, _login);
      }
    }
    

    代码解释:
    下午补充。

    相关文章

      网友评论

        本文标题:Flutter:一份无瑕疵的登录页代码

        本文链接:https://www.haomeiwen.com/subject/qkmruqtx.html