美文网首页
Flutter Go 源码分析(四)

Flutter Go 源码分析(四)

作者: Hedgehog___ | 来源:发表于2019-06-06 23:02 被阅读0次
    - (7)WidgetPage--组件列表页面

    WidgetPage构造函数:

    final db;
      final CatControlModel catModel;
      // WidgetPage(this.db):super(){
      //   catModel = new CatControlModel();
      // }
      WidgetPage(this.db)
          : catModel = new CatControlModel(),
            super();
    
    
      @override
      SecondPageState createState() => new SecondPageState(catModel);
    
    1. CatControlModel
      这里的db没看到有地方用到,主要看CatControlModel,这个类是用来对各种widget组件列表进行存取的工具(我暂时这么理解):
    final String table = 'cat';
      Sql sql;
      CatControlModel() {
        sql = Sql.setTable(table);
      }
    
      /// 获取一级类目
      Future<List> mainList() async{
        List listJson =  await sql.getByCondition(conditions: {'parentId': 0});
        List<Cat> cats = listJson.map((json) {
            return new Cat.fromJSON(json);
        }).toList();
        return cats;
      }
    
      // 获取Cat不同深度与parent的列表
      Future<List<Cat>> getList([Cat cat]) async{
    
    
        if (cat == null) {
          cat = new Cat(depth: 1, parentId: 0);
        }
        // print("cat in getList ${cat.toMap()}");
        List listJson =  await sql.getByCondition(conditions: cat.toSqlCondition());
        List<Cat> cats = listJson.map((json) {
          return new Cat.fromJSON(json);
        }).toList();
        return cats;
      }
    
      // 通过name获取Cat对象信息
      Future<Cat> getCatByName(String name) async {
        List json = await sql.getByCondition(conditions: {'name': name});
        if (json.isEmpty) {
          return null;
        }
        return new Cat.fromJSON(json.first);
      }
    

    cat: wedget组件模型,自行去代码中查看。

    1. SecondPageState
      initState初始化方法里面进行通过CatControlModel获取catList操作并存储到categories 数组。
    • build函数:
    Widget build(BuildContext context) {
        super.build(context);
        if (categories.length == 0) {
          return ListView(
            children: <Widget>[new Container()],
          );
        }
        return Container(
          color: Theme.of(context).backgroundColor,
          child: this.buildGrid(),
        );
      }
    

    主要代码实现在buildGrid方法里面的CateCard实例对象。
    我这里就不一一解释了没有什么难点的地方我就把注释写的详细一点直接上代码了。
    结构:CateCard(最外层包括圆角背景图和icon等)-->_buildWidgetContainer(卡牌列表项出来头部icon和title)-->WidgetItemContainer(所有的列表项,不包括背景图)-->WidgetItem(每个列表的item项).

    • CateCard
    Widget build(BuildContext context) {
        double screenWidth = MediaQuery.of(context).size.width;
        widget.category.name = widget.category.name.replaceFirst(
            //首字母转为大写
            widget.category.name.substring(0, 1),
            widget.category.name.substring(0, 1).toUpperCase());
            
        return Container(
          width: screenWidth,
          padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
          child: Stack(
            children: <Widget>[
              Container(
                width: screenWidth - 20,
                margin: const EdgeInsets.only(top: 30.0, bottom: 0.0),//外边距 每个卡牌上面的留白
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(4.0),
                ),
                child: Column(
                  children: <Widget>[
                    Container(//头部title
                      width: screenWidth - 20,
                      padding: const EdgeInsets.only(left: 65.0, top: 3.0),
                      height: 30.0,
                      child: Text(
                        widget.category.name,
                        style: TextStyle(
                          color: Theme.of(context).primaryColor,
                          fontSize: 18.0,
                        ),
                      ),
                    ),
                    _buildWidgetContainer(),//卡牌列表
                  ],
                ),
              ),
              Positioned(//头部icon
                left: 0.0,
                top: 0.0,
                child: Container(
                  height: 60.0,
                  width: 60.0,
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(30.0),
                  ),
                  child: Center(
                    child: Container(
                      decoration: BoxDecoration(
                        color: Theme.of(context).primaryColor,
                        borderRadius: BorderRadius.circular(23.0),
                      ),
                      height: 46.0,
                      width: 46.0,
                      child: Icon(
                        WidgetName2Icon.icons[widget.category.name],
                        color: Colors.white,
                        size: 30.0,
                      ),
                    ),
                  ),
                ),
              )
            ],
          ),
        );
      }
    
    
    • _buildWidgetContainer:
    Widget _buildWidgetContainer() {
        if (this._firstChildList.length == 0) {
          return Container();
        }
        return Container(
          padding: const EdgeInsets.only(bottom: 10.0, top: 5.0),
          decoration: BoxDecoration(
            image: DecorationImage(//每个模块的背景
              image: AssetImage('assets/images/paimaiLogo.png'),
              alignment: Alignment.bottomRight
            ),
          ),
          child: WidgetItemContainer(//整个列表项
            categories: this._firstChildList,
            columnCount: 3,
            isWidgetPoint:false
          ),
        );
      }
    
    • _buildColumns进行列表构建
    List<Widget> _buildColumns(context) {
        List<Widget> _listWidget = [];
        List<Widget> _listRows = [];
        int addI;
        for (int i = 0, length = categories.length; i < length; i += columnCount) {
          _listRows = [];
          for (int innerI = 0; innerI < columnCount; innerI++) {
            addI = innerI + i;
            if (addI < length) {
              dynamic item = categories[addI];
              _listRows.add(
                Expanded(
                  flex: 1,
                  child: WidgetItem(
                    title: item.name,
                    onTap: () {
                      if (isWidgetPoint) {
                        String targetName = item.name;
                        String targetRouter = '/category/error/404';
                        widgetDemosList.forEach((item) {
                          if (item.name == targetName) {
                            targetRouter = item.routerName;
                          }
                        });
                        Application.router.navigateTo(context, "$targetRouter", transition: TransitionType.inFromRight);
                      } else {
                        Application.router
                            .navigateTo(context, "/category/${item.name}", transition: TransitionType.inFromRight);
                      }
                    },
                    index: addI,
                    totalCount: length,
                    rowLength: columnCount,
                    textSize: isWidgetPoint ? 'middle' : 'small',
                  ),
                ),
              );
            } else {
              _listRows.add(
                Expanded(
                  flex: 1,
                  child: Container(),
                ),
              );
            }
          }
          _listWidget.add(
            Row(
              children: _listRows,
            ),
          );
        }
        return _listWidget;
      }
    
    • WidgetItem进行列表项构建和分割线的绘制
    Widget build(BuildContext context) {
        _widgetName = title.replaceFirst(
            //首字母转为大写
            title.substring(0, 1),
            title.substring(0, 1).toUpperCase());
        Icon widgetIcon;
        if (WidgetName2Icon.icons[_widgetName] != null) {
          widgetIcon = Icon(WidgetName2Icon.icons[_widgetName]);
        } else {
          widgetIcon = Icon(
            Icons.crop,
          );
        }
        final textStyle = (textSize == 'middle')
            ? TextStyle(fontSize: 13.8, fontFamily: 'MediumItalic')
            : TextStyle(fontSize: 16.0);
        return InkWell(
          onTap: onTap,
          child: Container(
            decoration: new BoxDecoration(
              border: _buildBorder(context),//分割线
            ),
            padding: const EdgeInsets.symmetric(vertical: 30.0, horizontal: 10.0),
            height: 150.0,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                widgetIcon,
                SizedBox(
                  height: 8.0,
                ),
                Text(_widgetName, style: textStyle),
              ],
            ),
          ),
        );
      }
    

    到这里第二个主要页面的布局就已经完成啦。

    相关文章

      网友评论

          本文标题:Flutter Go 源码分析(四)

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