Flutter开发规范

Flutter开发规范

中交兴路使用Flutter框架开发规范,大家都可以贡献自己的想法,可以通过沟通或提交分支的形式表达自己想法,讨论后达成共识就可以合并到主干,文档采用markdown语法来书写,每个版本会生成相关pdf文档

目录结构规范

目录规范
  1. lib文件夹是flutter主要代码目录,通常不会直接在根目录下直接创建dart文件,而是会根据功能点、模块、属性等创建子文件夹,在相应子文件夹中创建相应dart文件,当然子文件下依然可以再创建文件夹,将目标文件所属角色细化;

  2. 文件夹通常是小写单词,小驼峰法使用较少,不推荐使用下划线连接法;

  3. 通常main(mian.dart程序入口)会直接创建在根目录下;

命名规范

  1. 文件和文件夹命名规范

单词全部小写,多个单词时中间采用英文下划线分割

文件和文件夹命名
  1. 常量和变量命名规范

常量和变量命名采用小驼峰命名法,第一个单词小写,其他单词首字母大写。 代码如下:

/// 常量命名
const String key = 'LDDRDS323DRFDD';

/// 变量命名
String personName = '张三';
int age = 10;
  1. 类的名称命名规范

类名采用大驼峰命名法。所有单词首字母也大写,不使用分隔符。
私有类命名加英文下划线前缀,其它部分遵循类名称命名规则,采用大驼峰命名法。

属性命名使用小驼峰命名法,第一个单词小写,其他单词首字母大写,不使用分割符
私有属性加英文下划线前缀,其它部分遵循属性命名规则

class Person{
   final String name;        /// 名字
   final String closthColor; /// 衣服颜色
   String _sex;              /// 私有属性,以英文下划线开始
}

class _PrivateInfo{
   final String bankPassword;        /// 银行卡密码
   final String safePassword;        /// 保险柜密码

}

class BankCardTile{          /// 多个单词命名规则
   final String title;
   final int index;
}
  1. 方法命名规范

方法命名使用小驼峰命名法,第一个单词首字母小写,其他单词首字母大写,不使用分割符

class LoginPage{
  
  Future<bool> login(String userName, String password){
    /// code
  }

  void changeLoginStyle(LoginStyle style){ /// 改变登录方式
    /// code
  }
}

私有方法加英文下划线前缀

 class LoginPage{
    Future<bool> _sendMsgCode(String phoneName){
    /// code
  }
 }
  1. 图片命名单词全部小写,多个单词时中间采用英文下划线分割,

注意:flutter不支持中文,中文名字的图片在andriod系统中无法识别

  1. 枚举类命名规则

枚举名采用大驼峰命名法。第一个单词首字母大写,其他单词首字母也大写,不使用分隔符。

枚举值采用小驼峰命名法,第一个单词首字母小写,其他单词首字母大写。

  ///枚举命名采取大驼峰命名, 枚举值得采用小驼峰命名
  enum BankCardListType {
    myCard, // 我的银行卡列表
    cleanType, // 结算对象银行卡列表
  }

代码规范

  1. if else使用大括号,尽可能不省略;
if (yet) {
 /// code
}
  1. 注意使用@required、assert
Future sendRequestWithURL({
  @required String urlString,
  @required String requestId,
  String jsonParams = "",
  RequestType requestType = RequestType.post,
  Map<String, dynamic> headers = const {},
  Map<String, dynamic> params = const {},
  bool isShowLog = false,
  bool isFormData = false,
  int timeout = 5000,
}) async {
  assert(urlString != null);
  assert(urlString != '');
  assert(headers != null);
  assert(params != null);
  assert(requestId != null);
}
  1. 函数体代码不宜过多,最好在20 - 30行以内; 一个方法中尽量只做一件事。

  2. 控制嵌套层数,最好能控制在4层

  @override
  Widget build(BuildContext context) {
    CustomThemeData currentTheme = context.watch<ThemesManager>().currentTheme;
    return Scaffold(
      appBar: UniversalWidgets.customAppBar(context,title:' 添加银行卡'),
      body: SafeArea(
        child: SingleChildScrollView(
          child: Container(
              color: currentTheme.pageBackgroundColor,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Divider(height: 10, color: currentTheme.pageBackgroundColor),
                  SizedBox(height: 320, child: _listView(context)),
                  Container(
                    margin: EdgeInsets.fromLTRB(0, 45.5, 0, 0),
                    child: _saveButtonWidget(),
                  )
                ],
              )),
        ),
      ),
    );
  }
  1. 代码长度不要超过100个字符的宽度,也是Andriod studio折行宽度(下图红色框中的白线就是100个字符的位置)


    折行线
  2. 类文件的代码总度长度尽量控制在1000行以内,超过1000行考虑拆分功能。

  3. 封装、继承、混入、接口在开发过程常要多运用;相关知识点参考
    https://www.jianshu.com/p/62e02f239f74

  4. 在既要import导入,又需要export导出文件时,一定先全部import再export,不要交替进行。

library zjxl_digital_user_center;

import 'package:flutter/cupertino.dart';
import 'package:zjxl_digital_user_center/src/user_center_config.dart';

export 'package:zjxl_digital_user_center/src/user_center_config.dart';
export 'package:zjxl_digital_user_center/src/login/login_page.dart';
export 'package:zjxl_digital_user_center/src/pages_config.dart';

typedef UserCenterCallBack =  Function(BuildContext context,dynamic response);

  1. 不建议使用new创建相关对象,直接对象加()就可以创建对象,
    new Widget()与Widget()完全相同。
  2. 类、属性、方法的访问权限控制,如果不希望外部调用则设为私有,在开发过程中要将类、属性、方法的访问权限考虑进去,不能一味的全部开放,全部开发意味着外部调用方法和属性或初化类对象是可以正确操作和与你的设计是相符的。
class _AddBankCardPageState extends State<AddBankCardPage> {
  BankCardModel _selectedCard;
  ScrollController _scrollController = new ScrollController(); // listView 控制器

  List<InputTextTileStyle> _inputTileStyles = [];
  List<TextEditingController> _controllers = [];

  TextEditingController _cardTypeController = TextEditingController(text: '对私');
  TextEditingController _bankOfDepositController =
      TextEditingController(text: '建设银行');

  TextEditingController _cardNumberController = TextEditingController();
  TextEditingController _ownerController = TextEditingController();
  TextEditingController _idNumberController = TextEditingController();
  TextEditingController _phoneNumberController = TextEditingController();


  // 返回按钮点击,私有方法
  void _leadingButtonClick() {
    EasyLoading.dismiss();
    Navigator.of(context).pop();
  }
  1. 编码过程中习惯性使用“Reformat Code with dartfmt”,对编写的代码时进行整理


    image.png
  2. dispose()方法的释放资源;

 class _QRScanCodeState extends State<QRScanCode> with TickerProviderStateMixin {
 QRCaptureController _captureController = QRCaptureController();
 Animation<Alignment> _animation;
 AnimationController _animationController;

 bool _isTorchOn = false;
 bool _isPop = true;

 String _captureText = '';

 void dispose() {
   _animationController.dispose();
   super.dispose();
 }

 @override
 void initState() {
   super.initState();

   _captureController.onCapture((data) {
     print('onCapture----$data');
     if (data != null) {

     }
     _captureText = data;
    _animationController =
       AnimationController(vsync: this, duration: Duration(seconds: 1));
   _animation =
       AlignmentTween(begin: Alignment.topCenter, end: Alignment.bottomCenter)
           .animate(_animationController)
             ..addListener(() {
               setState(() {});
             })
             ..addStatusListener((status) {
               if (status == AnimationStatus.completed) {
                 _animationController.reverse();
               } else if (status == AnimationStatus.dismissed) {
                 _animationController.forward();
               }
             });
   _animationController.forward();
 }

  1. 实时处理报错(error)和警告(warning);

注释规范

  1. 单行注释,使用 // 或///;
 ///枚举命名采取大驼峰命名, 枚举值得采用小驼峰命名
 enum BankCardListType {
   myCard, // 我的银行卡列表
   cleanType, // 结算对象银行卡列表
 }

  1. 多行注释以 /* 开始, 以 */ 结束
/**
  * uri: 请求接口时的uri(必填)
  * requestId:本次请求的惟一id(必填)
  * requestType: 请求类型,默认post
  * headers:请求时head参数,传入时将会和公共head一块传入
  * params: 请求的参数
*/
class BaseRequest {

 Future sendRequest({
   @required String uri,
   @required String requestId,
   RequestType requestType = RequestType.post
   Map<String, dynamic> headers = const {},
   Map<String, dynamic> params = const {},
   bool isFormData = false,
 }) {
   GlobalRequestConfig config = GlobalConfigStorage.globalRequestConfig;
   return this.sendRequestWithHostURI(
       host: config.baseUrl,
       uri: uri,
       requestId: requestId,
       jsonParams: jsonParams,
       requestType: requestType,
       isFormData: isFormData,
       headers: headers,
       params: params,
       isShowLog: config.isShowLog,
       timeout: config.timeout);
 }
  1. 文档注释使用 ///, dart推荐的文档注释
/// ThemesManager 自定义主题使用方法:
/// 在main函数中监听 ThemesManager.instance
/// ```dart
/// Future<void> main() async {
///  runApp(
///    MultiProvider(
///      providers: [
///        ChangeNotifierProvider(
///          create: (_) => ThemesManager.instance,
///        )
///      ],
///      child: MyApp(),
///    )
///  );
/// }
///  ```
/// 在使用的区域 通过以下代码来获取当前的主题
/// ```dart
/// CustomThemeData currentTheme = context.watch<ThemesManager>().currentTheme;
/// 通过以下代码获取当前主题颜色,主题颜色参见CustomThemeData类
/// Color mainColor = currentTheme.mainColor;
///
/// 通过以下代码获取需要根据主题变换的图片,需要在主题的images目录中添加
/// Image icon = currentTheme.themeImage('cargo_icon_selected.png');
///
/// ```
///

class ThemesManager with ChangeNotifier{
  /// 主题列表
  List<CustomThemeData> _themes;
  /// 当前主题
  CustomThemeData _currentTheme;
  int _currentThemeIndex = 0;

  factory ThemesManager() =>_getInstance();
  static ThemesManager get instance => _getInstance();
  static ThemesManager _instance;

  get currentThemeIndex{
      return _currentThemeIndex;
  }
  ThemesManager._internal() {

      _themes = List();
      Theme1 theme1 = Theme1();
      Theme2 theme2 = Theme2();
      _themes.add(theme1);
      _themes.add(theme2);
  }
}
  1. 在新添加类文件顶部要添加开发者相关信息,格式如下
    /**
     * 描述:注册时部上传位置SDK时的配置文件
     * 作者:xxx
     * 建立时间: 2020/11/23
     */
     class RegisterConfig {
         /// 环境:“debug”测试,“release”正式,默认release(必填)
         final String environment;
    
         /// ios app bundleId,该bundleId须在交通部平台注册(必填)
         final String iosAppId;
    
         /// ios App 在交通部注册时的appSecurity(必填)
         final String iosAppSecurity;
    
         /// ios App 在交通部注册时的enterpriseSenderCode(必填)
         final String iosEnterpriseSenderCode;
     }
    
    

格式规范

组件开发规范

其他规范

markdown 文件编写帮助

https://maxiang.io/
https://shd101wyy.github.io/markdown-preview-enhanced/#/zh-cn/markdown-basics

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Java中有俩种数据类型,其中主要有8中基本数据类型和引用数据类型,除了8中基本数据类型以外都是引用数据类型,8中...
    徐嘉迪阅读 423评论 0 0
  • 01.01_计算机基础知识(计算机概述)(了解) A:什么是计算机?计算机在生活中的应用举例计算机(Compute...
    冰川_阅读 281评论 0 1
  • 1、 Java语言有哪些特点 (1)简单易学、有丰富的类库 (2)面向对象(Java最重要的特性,让程序耦合度更低...
    cuixiaoyan阅读 312评论 0 0
  • 对于刚入行或者入行几年的程序员,或多或少,都有一点代码规范的问题,有些是没法子,各种需求变更,或入手各种别人写了一...
    SingleoD阅读 8,303评论 41 160
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,550评论 16 22