Flutter代码规范

作者: oldSix_Zhu | 来源:发表于2019-04-30 11:07 被阅读3次

    Flutter代码通常涉及构建相当深的树状数据结构,在看官方的Flutter例子代码的时候,你会被一层一层的括号套的眼睛都花了...
    所以我根据之前的web开发经验总结了一点Flutter代码书写规范。
    用咸鱼的fish-redux也可以使代码分层更明确一点,在我的另一篇文章会记录使用过程。

    我们先看个我写的邮箱登录注册的界面例子:

    如果是普通写代码的话,就会是这样:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:fitforce_coach/module/base/controller/BaseWidget.dart';
    import 'package:fitforce_coach/utiliy/TYTool.dart';
    
    class EmailController extends StatefulWidget {
      // EmailControllerState emailState =
      @override
      State<StatefulWidget> createState() {
        return EmailControllerState();
      }
    }
    
    class EmailControllerState extends State<EmailController> {
      //默认闭合眼睛
      bool closeEye = true;
      //邮箱的控制器
      TextEditingController emailControl = TextEditingController();
      //密码的控制器
      TextEditingController passwordControl = TextEditingController();
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        //设置状态栏颜色
        SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
        return Scaffold(
          body: buildBody(context),
        );
      }
    
    //视图-------------------------------------
      Widget buildBody(BuildContext context) {
        return Stack(
          children: <Widget>[
            Image.asset(
              'images/login/login_bg.png',
              width: TYTool.getScreenWidth(context),
              height: TYTool.getScreenHeight(context),
              fit: BoxFit.fill,
            ),
            //全屏取消编辑手势
            addCancelEditView(context),
            Column(
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.only(
                      top: TYTool.getSysStatsHeight(context) + 16.0),
                ),
                Stack(
                  // alignment: Alignment.centerLeft,
                  children: <Widget>[
                    //返回按钮
                    Align(
                      alignment: Alignment.centerLeft,
                      child: Container(
                        height: 30.0,
                        width: 30.0,
                        margin: EdgeInsets.only(left: 10.0),
                        child: IconButton(
                          padding: EdgeInsets.all(0.0),
                          icon: Icon(
                            Icons.arrow_back_ios,
                            color: Colors.white,
                          ),
                          onPressed: () {
                            popLastController(context);
                          },
                        ),
                      ),
                    ),
                    //logo图片
                    Align(
                      alignment: Alignment.center,
                      child: Image.asset(
                        'images/login/login_logo.png',
                        width: 112.0,
                        height: 22.0,
                      ),
                    ),
                  ],
                ),
                Container(
                  margin: EdgeInsets.fromLTRB(52.0, 46.0, 52.0, 10.0),
                  child: Column(
                    children: <Widget>[
                      //题目
                      Container(
                        margin: EdgeInsets.only(bottom: 30.0),
                        //宽度尽可能大
                        width: double.infinity,
                        child: Text(
                          '邮箱登录',
                          textDirection: TextDirection.ltr,
                          textAlign: TextAlign.start,
                          style: TextStyle(
                            // background: backgroundPaint,
                            color: Colors.white,
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                      //邮箱
                      Theme(
                        data: ThemeData(
                            primaryColor: Colors.white, hintColor: Colors.white54),
                        child: TextField(
                          style: TextStyle(fontSize: 14.0, color: Colors.white),
                          keyboardType: TextInputType.emailAddress,
                          cursorColor: Color(0xFF20C6BA),
                          cursorWidth: 1.5,
                          controller: emailControl,
                          decoration: InputDecoration(
                            hintText: '请输入邮箱地址',
                          ),
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(bottom: 30.0),
                      ),
                      Stack(
                        children: <Widget>[
                          //验证码
                          Theme(
                            data: ThemeData(
                                primaryColor: Colors.white,
                                hintColor: Colors.white54),
                            child: TextField(
                              style: TextStyle(fontSize: 14.0, color: Colors.white),
                              cursorColor: Color(0xFF20C6BA),
                              cursorWidth: 1.5,
                              controller: passwordControl,
                              obscureText: closeEye,
                              decoration: InputDecoration(
                                hintText: '请输入密码',
                              ),
                            ),
                          ),
                          //小眼睛
                          Container(
                            margin: EdgeInsets.fromLTRB(
                                TYTool.getScreenWidth(context) - 104.0 - 38.0,
                                10.0,
                                20.0,
                                10.0),
                            height: 18.0,
                            child: MaterialButton(
                              padding: EdgeInsets.all(0.0),
                              highlightColor: Colors.transparent,
                              splashColor: Colors.transparent,
                              child: Image.asset(
                                closeEye
                                    ? 'images/login/btn_login_eye_close.png'
                                    : 'images/login/btn_login_eye_open.png',
                                width: 18.0,
                                height: 18.0,
                              ),
                              onPressed: () {
                                setState(() {
                                  closeEye = !closeEye;
                                });
                              },
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
                //密码登录按钮
                Container(
                  margin: EdgeInsets.fromLTRB(52.0, 0.0, 52.0, 15.0),
                  //垂直居中水平靠左对齐
                  alignment: Alignment.centerRight,
                  height: 18.0,
                  child: MaterialButton(
                    padding: EdgeInsets.all(0.0),
                    minWidth: 60.0,
                    height: 16.0,
                    //水波纹颜色透明
                    splashColor: Colors.transparent,
                    highlightColor: Colors.transparent,
                    child: Text(
                      '忘记密码?',
                      textDirection: TextDirection.ltr,
                      textAlign: TextAlign.left,
                      style: TextStyle(
                        color: Color(0xFF20C6BA),
                        fontSize: 12.0,
                      ),
                    ),
                    onPressed: () {
                      print('忘记密码?');
                    },
                  ),
                ),
                //未注册...
                Text(
                  '未注册邮箱,输入密码可进行注册并登录 ',
                  textDirection: TextDirection.ltr,
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    // background: backgroundPaint,
                    color: Colors.white.withOpacity(0.4),
                    fontSize: 10.0,
                  ),
                ),
                //登录
                MaterialButton(
                  height: 45.0,
                  minWidth: TYTool.getScreenWidth(context) - 104.0,
                  color: Color(0xFF20C6BA),
                  child: Text(
                    '登录',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 15.0,
                    ),
                  ),
                  onPressed: () {
                    // login(context);
                  },
                ),
              ],
            ),
            //loading
            loadingDialog,
          ],
        );
      }
    }
    

    你会被这一层一层的括号套的眼睛都花了...
    所以我建议书写规范就是:
    1、把布局控件放在一起,把展示控件用Container包裹起来写到方法里创建。
    2、使用 ‘尾随逗号’,最后一个属性后加个“,”,这样在格式化代码的时候就会自动换行。
    3、视图和视图写在一起,手势方法和手势方法写在一起,网络请求和网络请求写在一起
    当遵循这3个规范之后上面的代码就变成了这样:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:fitforce_coach/module/base/controller/BaseWidget.dart';
    import 'package:fitforce_coach/utiliy/TYTool.dart';
    
    class EmailController extends StatefulWidget {
      // EmailControllerState emailState =
      @override
      State<StatefulWidget> createState() {
        return EmailControllerState();
      }
    }
    
    class EmailControllerState extends State<EmailController> {
      //默认闭合眼睛
      bool closeEye = true;
      //邮箱的控制器
      TextEditingController emailControl = TextEditingController();
      //密码的控制器
      TextEditingController passwordControl = TextEditingController();
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        //设置状态栏颜色
        SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
        return Scaffold(
          body: buildBody(context),
        );
      }
    
    //视图-------------------------------------
      Widget buildBody(BuildContext context) {
        return Stack(
          children: <Widget>[
            //背景
            bgImage(context),
            //全屏取消编辑手势
            addCancelEditView(context),
            Column(
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.only(
                      top: TYTool.getSysStatsHeight(context) + 16.0),
                ),
                Stack(
                  // alignment: Alignment.centerLeft,
                  children: <Widget>[
                    //返回按钮
                    Align(
                      alignment: Alignment.centerLeft,
                      child: backButton(context),
                    ),
                    //logo图片
                    Align(
                      alignment: Alignment.center,
                      child: topImage(context),
                    ),
                  ],
                ),
                Container(
                  margin: EdgeInsets.fromLTRB(52.0, 46.0, 52.0, 10.0),
                  child: Column(
                    children: <Widget>[
                      //题目
                      topTitle(context),
                      //邮箱
                      emailTextField(context),
                      Padding(
                        padding: EdgeInsets.only(bottom: 30.0),
                      ),
                      Stack(
                        children: <Widget>[
                          //验证码
                          codeTextField(context),
                          //小眼睛
                          eyeButton(context),
                        ],
                      ),
                    ],
                  ),
                ),
                //密码登录按钮
                forgetPasswordButton(context),
                //未注册...
                detailText(context),
                //登录
                loginButton(context),
              ],
            ),
            //loading
            loadingDialog,
          ],
        );
      }
    
     //view---------------------------------------------
      //背景图片
      Widget bgImage(BuildContext context) {
        return Image.asset(
          'images/login/login_bg.png',
          width: TYTool.getScreenWidth(context),
          height: TYTool.getScreenHeight(context),
          fit: BoxFit.fill,
        );
      }
    
      //返回按钮
      Widget backButton(BuildContext context) {
        return Container(
          height: 30.0,
          width: 30.0,
          margin: EdgeInsets.only(left: 10.0),
          child: IconButton(
            padding: EdgeInsets.all(0.0),
            icon: Icon(
              Icons.arrow_back_ios,
              color: Colors.white,
            ),
            onPressed: () {
              popLastController(context);
            },
          ),
        );
      }
    
    //logo图片
      Widget topImage(BuildContext context) {
        return Image.asset(
          'images/login/login_logo.png',
          width: 112.0,
          height: 22.0,
        );
      }
    
    //邮箱登录
      Widget topTitle(BuildContext context) {
        return Container(
          margin: EdgeInsets.only(bottom: 30.0),
          //宽度尽可能大
          width: double.infinity,
          child: Text(
            '邮箱登录',
            textDirection: TextDirection.ltr,
            textAlign: TextAlign.start,
            style: TextStyle(
              // background: backgroundPaint,
              color: Colors.white,
              fontSize: 18.0,
            ),
          ),
        );
      }
    
    //邮箱
      Widget emailTextField(BuildContext context) {
        return Theme(
          data: ThemeData(primaryColor: Colors.white, hintColor: Colors.white54),
          child: TextField(
            style: TextStyle(fontSize: 14.0, color: Colors.white),
            keyboardType: TextInputType.emailAddress,
            cursorColor: Color(0xFF20C6BA),
            cursorWidth: 1.5,
            controller: emailControl,
            decoration: InputDecoration(
              hintText: '请输入邮箱地址',
            ),
          ),
        );
      }
    
    //验证码
      Widget codeTextField(BuildContext context) {
        return Theme(
          data: ThemeData(primaryColor: Colors.white, hintColor: Colors.white54),
          child: TextField(
            style: TextStyle(fontSize: 14.0, color: Colors.white),
            cursorColor: Color(0xFF20C6BA),
            cursorWidth: 1.5,
            controller: passwordControl,
            obscureText: closeEye,
            decoration: InputDecoration(
              hintText: '请输入密码',
            ),
          ),
        );
      }
    
    //小眼睛
      Widget eyeButton(BuildContext context) {
        return Container(
          margin: EdgeInsets.fromLTRB(
              TYTool.getScreenWidth(context) - 104.0 - 38.0, 10.0, 20.0, 10.0),
          height: 18.0,
          child: MaterialButton(
            padding: EdgeInsets.all(0.0),
            highlightColor: Colors.transparent,
            splashColor: Colors.transparent,
            child: Image.asset(
              closeEye
                  ? 'images/login/btn_login_eye_close.png'
                  : 'images/login/btn_login_eye_open.png',
              width: 18.0,
              height: 18.0,
            ),
            onPressed: () {
              didClickEyeButton(context);
            },
          ),
        );
      }
    
    //忘记密码
      Widget forgetPasswordButton(BuildContext context) {
        return Container(
          margin: EdgeInsets.fromLTRB(52.0, 0.0, 52.0, 15.0),
          //垂直居中水平靠左对齐
          alignment: Alignment.centerRight,
          height: 18.0,
          child: MaterialButton(
            padding: EdgeInsets.all(0.0),
            minWidth: 60.0,
            height: 16.0,
            //水波纹颜色透明
            splashColor: Colors.transparent,
            highlightColor: Colors.transparent,
            child: Text(
              '忘记密码?',
              textDirection: TextDirection.ltr,
              textAlign: TextAlign.left,
              style: TextStyle(
                color: Color(0xFF20C6BA),
                fontSize: 12.0,
              ),
            ),
            onPressed: () {
              didClickForgetPasswordButton(context);
            },
          ),
        );
      }
    
    //未注册....
      Widget detailText(BuildContext context) {
        return Text(
          '未注册邮箱,输入密码可进行注册并登录 ',
          textDirection: TextDirection.ltr,
          textAlign: TextAlign.center,
          style: TextStyle(
            // background: backgroundPaint,
            color: Colors.white.withOpacity(0.4),
            fontSize: 10.0,
          ),
        );
      }
    
    //登录
      Widget loginButton(BuildContext context) {
        return MaterialButton(
          height: 45.0,
          minWidth: TYTool.getScreenWidth(context) - 104.0,
          color: Color(0xFF20C6BA),
          child: Text(
            '登录',
            style: TextStyle(
              color: Colors.white,
              fontSize: 15.0,
            ),
          ),
          onPressed: () {
            // login(context);
          },
        );
      }
    
    //其他事件-------------------------------------------
    //忘记密码
      void didClickForgetPasswordButton(BuildContext context) {
        print('忘记密码?');
      }
    
    //点击眼睛
      void didClickEyeButton(BuildContext context) {
        setState(() {
          closeEye = !closeEye;
        });
      }
    
    //网络请求-------------------------------------------
    
    }
    

    会发现代码括号层级少了很多,总算能看得下去了...
    这里面有些我自己封装的框架和基类,直接使用有些方法会爆红的,仅仅是展示代码书写规范,这样整理后条理清晰了很多,在复杂的页面更能体现出来。

    相关文章

      网友评论

        本文标题:Flutter代码规范

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