B站视频

https://www.bilibili.com/vide...

本节目标

  • 了解 supernova 代码生成器作用
  • 导入 xd 设计稿
  • 如何高效使用生成代码

正文

代码生成器

  • supernova
  • imgcook

有潜力加入代码生成功能

  • lanhuapp
  • mockplus

supernova 代码生成器

https://supernova.io/

导入 xd 设计稿,生成代码

商业设计稿不好直接分享, 可以加微信联系 ducafecat

编写用户中心界面代码

组织代码结构

class _AccountPageState extends State<AccountPage> {  // 个人页面 头部  Widget _buildUserHeader() {}  // 列表项  Widget _buildCell() {}  @override  Widget build(BuildContext context) {    final appState = Provider.of<AppState>(context);    return SingleChildScrollView(      child: Column(        children: <Widget>[          _buildUserHeader(),          _buildCell(),        ],      ),    );  }}

直接使用生成的代码

  • 个人页面 头部
  Widget _buildUserHeader() {    return Container(              height: 333,              child: Stack(                alignment: Alignment.center,                children: [                  Positioned(                    left: 0,                    right: 0,                    child: Container(                      height: 333,                      decoration: BoxDecoration(                        color: AppColors.primaryBackground,                      ),                      child: Column(                        mainAxisAlignment: MainAxisAlignment.end,                        crossAxisAlignment: CrossAxisAlignment.stretch,                        children: [                          Container(                            height: 2,                            decoration: BoxDecoration(                              color: AppColors.primaryElement,                            ),                            child: Container(),                          ),                        ],                      ),                    ),                  ),                  Positioned(                    left: 20,                    top: 40,                    right: 20,                    bottom: 21,                    child: Column(                      crossAxisAlignment: CrossAxisAlignment.stretch,                      children: [                        Container(                          height: 198,                          child: Column(                            crossAxisAlignment: CrossAxisAlignment.stretch,                            children: [                              Align(                                alignment: Alignment.topCenter,                                child: Container(                                  width: 108,                                  height: 108,                                  child: Stack(                                    alignment: Alignment.center,                                    children: [                                      Positioned(                                        top: 0,                                        child: Container(                                          width: 108,                                          height: 108,                                          decoration: BoxDecoration(                                            color: AppColors.primaryBackground,                                            boxShadow: [                                              Shadows.primaryShadow,                                            ],                                            borderRadius: Radii.k54pxRadius,                                          ),                                          child: Container(),                                        ),                                      ),                                      Positioned(                                        top: 10,                                        child: Image.asset(                                          "assets/images/image.png",                                          fit: BoxFit.none,                                        ),                                      ),                                    ],                                  ),                                ),                              ),                              Spacer(),                              Container(                                margin: EdgeInsets.only(bottom: 9),                                child: Text(                                  "Cameron Rogers",                                  textAlign: TextAlign.center,                                  style: TextStyle(                                    color: AppColors.primaryText,                                    fontFamily: "Montserrat",                                    fontWeight: FontWeight.w400,                                    fontSize: 24,                                  ),                                ),                              ),                              Text(                                "@boltrogers",                                textAlign: TextAlign.center,                                style: TextStyle(                                  color: AppColors.primaryText,                                  fontFamily: "Avenir",                                  fontWeight: FontWeight.w400,                                  fontSize: 16,                                ),                              ),                            ],                          ),                        ),                        Spacer(),                        Container(                          height: 44,                          child: FlatButton(                            onPressed: () => this.onButtonPressed(context),                            color: Color.fromARGB(255, 41, 103, 255),                            shape: RoundedRectangleBorder(                              borderRadius: BorderRadius.all(Radius.circular(6)),                            ),                            textColor: Color.fromARGB(255, 255, 255, 255),                            padding: EdgeInsets.all(0),                            child: Text(                              "Get Premium - \$9.99",                              textAlign: TextAlign.center,                              style: TextStyle(                                color: AppColors.secondaryText,                                fontFamily: "Montserrat",                                fontWeight: FontWeight.w400,                                fontSize: 18,                              ),                            ),                          ),                        ),                      ],                    ),                  ),                ],              ),            );  }
  • 列表项
  Widget _buildCell() {    return Container(              height: 60,              child: Stack(                alignment: Alignment.centerLeft,                children: [                  Positioned(                    left: 0,                    right: 0,                    child: Container(                      height: 60,                      decoration: BoxDecoration(                        color: AppColors.secondaryElement,                      ),                      child: Column(                        mainAxisAlignment: MainAxisAlignment.end,                        crossAxisAlignment: CrossAxisAlignment.stretch,                        children: [                          Container(                            height: 1,                            decoration: BoxDecoration(                              color: AppColors.primaryElement,                            ),                            child: Container(),                          ),                        ],                      ),                    ),                  ),                  Positioned(                    right: 0,                    child: Row(                      mainAxisAlignment: MainAxisAlignment.end,                      children: [                        Container(                          margin: EdgeInsets.only(right: 11),                          child: Text(                            "12",                            textAlign: TextAlign.right,                            style: TextStyle(                              color: AppColors.primaryText,                              fontFamily: "Avenir",                              fontWeight: FontWeight.w400,                              fontSize: 18,                            ),                          ),                        ),                        Container(                          width: 24,                          height: 24,                          margin: EdgeInsets.only(right: 20),                          child: Image.asset(                            "assets/images/icon.png",                            fit: BoxFit.none,                          ),                        ),                      ],                    ),                  ),                  Positioned(                    left: 0,                    child: Stack(                      alignment: Alignment.center,                      children: [                        Positioned(                          left: 0,                          right: 19,                          child: Container(),                        ),                        Positioned(                          left: 20,                          right: 0,                          child: Text(                            "Favorite channels",                            textAlign: TextAlign.left,                            style: TextStyle(                              color: AppColors.primaryText,                              fontFamily: "Montserrat",                              fontWeight: FontWeight.w400,                              fontSize: 18,                            ),                          ),                        ),                      ],                    ),                  ),                ],              ),            );  }

抽取代码 lib/common/widgets/app.dart

/// 10像素 DividerWidget divider10Px({Color bgColor = AppColors.secondaryElement}) {  return Container(    height: duSetWidth(10),    decoration: BoxDecoration(      color: bgColor,    ),  );}

修改代码 _buildUserHeader

  // 个人页面 头部  Widget _buildUserHeader() {    return Container(      height: duSetWidth(333),      child: Stack(        alignment: Alignment.center,        children: [          // 背景          Positioned(            left: 0,            right: 0,            child: Container(              height: duSetWidth(333),              decoration: BoxDecoration(                color: AppColors.primaryBackground,              ),              child: Column(                mainAxisAlignment: MainAxisAlignment.end,                crossAxisAlignment: CrossAxisAlignment.stretch,                children: [                  Container(                    height: duSetWidth(2),                    decoration: BoxDecoration(                      color: AppColors.tabCellSeparator,                    ),                    child: Container(),                  ),                ],              ),            ),          ),          Positioned(            left: 20,            top: 40,            right: 20,            bottom: 21,            child: Column(              crossAxisAlignment: CrossAxisAlignment.stretch,              children: [                // 头像                Container(                  height: duSetWidth(198),                  child: Column(                    crossAxisAlignment: CrossAxisAlignment.stretch,                    children: [                      Align(                        alignment: Alignment.topCenter,                        child: Container(                          width: duSetWidth(108),                          height: duSetWidth(108),                          child: Stack(                            alignment: Alignment.center,                            children: [                              Positioned(                                top: 0,                                child: Container(                                  width: duSetWidth(108),                                  height: duSetWidth(108),                                  decoration: BoxDecoration(                                    color: AppColors.primaryBackground,                                    boxShadow: [                                      Shadows.primaryShadow,                                    ],                                    borderRadius: BorderRadius.all(                                        Radius.circular(duSetWidth(108) / 2)),                                  ),                                  child: Container(),                                ),                              ),                              Positioned(                                top: 10,                                child: Image.asset(                                  "assets/images/account_header.png",                                  height: duSetWidth(88),                                  width: duSetWidth(88),                                  fit: BoxFit.fill,                                ),                              ),                            ],                          ),                        ),                      ),                      // 文字                      Spacer(),                      Container(                        margin: EdgeInsets.only(bottom: 9),                        child: Text(                          Global.profile.displayName,                          textAlign: TextAlign.center,                          style: TextStyle(                            color: AppColors.primaryText,                            fontFamily: "Montserrat",                            fontWeight: FontWeight.w400,                            fontSize: 24,                          ),                        ),                      ),                      Text(                        "@boltrogers",                        textAlign: TextAlign.center,                        style: TextStyle(                          color: AppColors.primaryText,                          fontFamily: "Avenir",                          fontWeight: FontWeight.w400,                          fontSize: 16,                        ),                      ),                    ],                  ),                ),                // 按钮                Spacer(),                Container(                  height: 44,                  child: FlatButton(                    onPressed: () => {},                    color: Color.fromARGB(255, 41, 103, 255),                    shape: RoundedRectangleBorder(                      borderRadius: BorderRadius.all(Radius.circular(6)),                    ),                    textColor: Color.fromARGB(255, 255, 255, 255),                    padding: EdgeInsets.all(0),                    child: Text(                      "Get Premium - \$9.99",                      textAlign: TextAlign.center,                      style: TextStyle(                        color: AppColors.primaryElementText,                        fontFamily: "Montserrat",                        fontWeight: FontWeight.w400,                        fontSize: 18,                      ),                    ),                  ),                ),              ],            ),          ),        ],      ),    );  }

修改代码 _buildCell

  // 列表项  Widget _buildCell({    String title,    String subTitle,    int number,    bool hasArrow = false,    VoidCallback onTap,  }) {    return GestureDetector(      onTap: onTap,      child: Container(        height: duSetWidth(60),        color: Colors.white,        child: Stack(          alignment: Alignment.centerLeft,          children: [            // 背景            Positioned(              left: 0,              right: 0,              child: Container(                height: duSetWidth(60),                decoration: BoxDecoration(                  color: AppColors.primaryBackground,                ),                child: Column(                  mainAxisAlignment: MainAxisAlignment.end,                  crossAxisAlignment: CrossAxisAlignment.stretch,                  children: [                    Container(                      height: duSetWidth(1),                      decoration: BoxDecoration(                        color: AppColors.tabCellSeparator,                      ),                      child: Container(),                    ),                  ],                ),              ),            ),            // 右侧            Positioned(              right: 0,              child: Row(                mainAxisAlignment: MainAxisAlignment.end,                children: [                  // 数字                  number == null                      ? Container()                      : Container(                          margin: EdgeInsets.only(right: 11),                          child: Text(                            number.toString(),                            textAlign: TextAlign.right,                            style: TextStyle(                              color: AppColors.primaryText,                              fontFamily: "Avenir",                              fontWeight: FontWeight.w400,                              fontSize: duSetFontSize(18),                            ),                          ),                        ),                  // 箭头                  hasArrow == false                      ? Container()                      : Container(                          width: duSetWidth(24),                          height: duSetWidth(24),                          margin: EdgeInsets.only(right: 20),                          child: Icon(                            Icons.arrow_forward_ios,                            color: AppColors.primaryText,                          ),                        ),                ],              ),            ),            // 标题            title == null                ? Container()                : Positioned(                    left: 20,                    child: Text(                      title,                      textAlign: TextAlign.left,                      style: TextStyle(                        color: AppColors.primaryText,                        fontFamily: "Montserrat",                        fontWeight: FontWeight.w400,                        fontSize: duSetFontSize(18),                      ),                    ),                  ),            // 子标题            subTitle == null                ? Container()                : Positioned(                    right: 20,                    child: Text(                      subTitle,                      textAlign: TextAlign.left,                      style: TextStyle(                        color: AppColors.primaryText,                        fontFamily: "Montserrat",                        fontWeight: FontWeight.w400,                        fontSize: duSetFontSize(18),                      ),                    ),                  ),          ],        ),      ),    );  }

修改代码 build

  @override  Widget build(BuildContext context) {    final appState = Provider.of<AppState>(context);    return SingleChildScrollView(      child: Column(        children: <Widget>[          _buildUserHeader(),          divider10Px(),          _buildCell(            title: "Email",            subTitle: "boltrogers@gmail.com",          ),          divider10Px(),          _buildCell(            title: "Favorite channels",            number: 12,            hasArrow: true,          ),          _buildCell(            title: "Bookmarks",            number: 294,            hasArrow: true,          ),          _buildCell(            title: "Popular categories",            number: 7,            hasArrow: true,          ),          divider10Px(),          _buildCell(            title: "Newsletter",            hasArrow: true,          ),          _buildCell(            title: "Settings",            hasArrow: true,          ),          divider10Px(),          _buildCell(            title: "Switch Gray Filter",            hasArrow: true,            onTap: () => appState.switchGrayFilter(),          ),          _buildCell(            title: "Log out",            hasArrow: true,            onTap: () => goLoginPage(context),          ),          divider10Px(),        ],      ),    );  }

技巧

  • vscode 固定代码

总结

资源

设计稿蓝湖预览

https://lanhuapp.com/url/lYuz1
密码: gSKl

蓝湖现在收费了,所以查看标记还请自己上传 xd 设计稿
商业设计稿文件不好直接分享, 可以加微信联系 ducafecat

代码

https://github.com/ducafecat/...