Flutter 实现钉钉消息列表效果(二)

266 阅读2分钟

上一篇: Flutter 实现钉钉消息列表效果(一)

pubspec.yaml 依赖
  flutter_screenutil: ^2.3.0 # 屏幕适配
  flutter_svg: ^0.18.0 # svg 图片加载
  nine_grid_view: ^1.0.5 # 显示九宫格头像(QQ头像、微信头像 ....)
实现效果如图

创建 DTMessageScreen
  • 构建 AppBar

  • 使用 Flutter 原生的 AppBar 进行对应属性设置

    AppBar buildAppBar(BuildContext context) {
        return AppBar(
          automaticallyImplyLeading: false,
          title: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              GestureDetector(
                child: CircleAvatar(
                  backgroundColor: kPrimaryColor,
                  radius: kSize40,
                  child: Text(
                    "江景",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
                onTap: () {
                  Scaffold.of(context).openDrawer();
                },
              ),
              Padding(
                padding: EdgeInsets.only(left: kSize24),
                child: Text(
                  "未连接",
                  style: TextStyle(color: kColor33, fontSize: kSize30),
                ),
              )
            ],
          ),
        );
      }
    
  • 构建搜索输入框 Widget

    • 创建 DTMessageSearchDecoration
    • 自定义设置视图,使用 Container, 设置上 decoration
    • 没有使用 TextFiled,原因是想点击之后跳转到另外一个界面 (TODO:)
    class DTMessageSearchDecoration extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          height: kSize70,
          margin: EdgeInsets.symmetric(horizontal: kSize36),
          decoration: BoxDecoration(
              color: kColorECEDED, borderRadius: BorderRadius.circular(kSize35)),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(left: kSize20, right: kSize16),
                child: Icon(Icons.search, color: kColor99),
              ),
              Text("搜索", style: TextStyle(color: kColor99))
            ],
          ),
        );
      }
    }
    
  • 实现日历 + 待办 + DING Widget

    • 创建 DTMessageTopQuick Widget
    • 使用 Column + Row 实现
  • 封装子组件 DTTopQuickItem,每个组件样式都是一样的,内容不一样,可以根据数据去渲染实现不同的 Item

class DTMessageTopQuick extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Padding(
          padding: EdgeInsets.symmetric(vertical: kSize32),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              DTTopQuickItem(
                  iconPath: "assets/icons/icon_calendar.svg",
                  title: "日历",
                  showDivider: true),
              DTTopQuickItem(
                  iconPath: "assets/icons/icon_backlog.svg",
                  title: "待办",
                  showDivider: true),
              DTTopQuickItem(
                  iconPath: "assets/icons/icon_ding.svg", title: "DING"),
            ],
          ),
        ),
        Divider(height: kSize1, color: kColorECEDED, indent: kSize36)
      ],
    );
  }
}
  • 单个 DTTopQuickItem

    • 自定义基础 StatelessWidget
    • 根据不同参数
      • iconPath 显示图片
      • title 显示文本
      • showDivider 是否需要显示后面竖杠
    • 小红圆点,Container 组件设置 BoxDecoration
class DTTopQuickItem extends StatelessWidget {
  final String iconPath;
  final String title;
  final bool showDivider;

  DTTopQuickItem(
      {@required this.iconPath,
      @required this.title,
      this.showDivider = false});

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        SvgPicture.asset(
          iconPath,
          width: kSize38,
          height: kSize38,
          color: kColor99,
        ),
        Padding(
          padding: EdgeInsets.only(left: kSize14),
          child: Text(
            title,
            style: TextStyle(
              color: kColor99,
            ),
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: kSize16),
          child: Container(
              width: kSize32,
              height: kSize32,
              alignment: Alignment.topCenter,
              decoration: BoxDecoration(
                  color: Colors.red,
                  borderRadius: BorderRadius.circular(kSize20)),
              child: Text(
                "6",
                style: TextStyle(color: Colors.white, fontSize: kSize24),
              )),
        ),
        showDivider
            ? Container(
                width: kSize1,
                height: kSize38,
                margin: EdgeInsets.only(left: kSize56),
                color: kColorECEDED,
              )
            : SizedBox(),
      ],
    );
  }
}

  • 实现待办事项
    • 创建 DTMessageTopMask Widget
    • Column + Row 来添加不同的组件
    • 添加的小组件都是不同的 svg 图片
class DTMessageTopMask extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Padding(
          padding: EdgeInsets.symmetric(vertical: kSize32),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Container(
                width: kSize160,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    SvgPicture.asset(
                      'assets/icons/icon_computer.svg',
                      width: kSize38,
                      height: kSize38,
                    ),
                    Container(
                      width: kSize1,
                      height: kSize38,
                      margin: EdgeInsets.only(left: kSize36),
                      color: kColorECEDED,
                    )
                  ],
                ),
              ),
              Expanded(
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    SvgPicture.asset(
                      'assets/icons/icon_at.svg',
                      width: kSize38,
                      color: Colors.orangeAccent,
                    ),
                    SvgPicture.asset(
                      'assets/icons/icon_star.svg',
                      width: kSize38,
                      color: kColor99,
                    ),
                    SvgPicture.asset(
                      'assets/icons/icon_timer.svg',
                      width: kSize38,
                      color: kColor99,
                    ),
                    SvgPicture.asset(
                      'assets/icons/icon_red_packet.svg',
                      width: kSize38,
                      color: kColor99,
                    ),
                    SvgPicture.asset(
                      'assets/icons/icon_list.svg',
                      width: kSize38,
                      color: kColor99,
                    ),
                  ],
                ),
              ),
              GestureDetector(
                child: Container(
                  width: kSize160,
                  alignment: Alignment.centerRight,
                  padding: EdgeInsets.only(right: kSize24),
                  child: SvgPicture.asset(
                    'assets/icons/icon_more.svg',
                    width: kSize38,
                    color: kColor99,
                  ),
                ),
                onTap: () {
                  Navigator.push(context,
                      MaterialPageRoute(builder: (BuildContext context) {
                    return DTMessageSetting();
                  }));
                },
              ),
            ],
          ),
        ),
        Divider(height: kSize1, color: kColorECEDED, indent: kSize36)
      ],
    );
  }
}

代码地址: gitee.com/shizidada/f…