美文网首页
flutter 中如何使用Wrap实现流布局

flutter 中如何使用Wrap实现流布局

作者: 小木虫666 | 来源:发表于2021-11-26 15:01 被阅读0次

    Wrap使用笔记

    Wrap是一个可以使子控件自动换行的控件,默认的方向是水平的,使用起来也很简单。

    首先看下他的构造方法:

      Wrap({
        Key key,
        this.direction = Axis.horizontal,   //排列方向,默认水平方向排列
        this.alignment = WrapAlignment.start,  //子控件在主轴上的对齐方式
        this.spacing = 0.0,  //主轴上子控件中间的间距
        this.runAlignment = WrapAlignment.start,  //子控件在交叉轴上的对齐方式
        this.runSpacing = 0.0,  //交叉轴上子控件之间的间距
        this.crossAxisAlignment = WrapCrossAlignment.start,   //交叉轴上子控件的对齐方式
        this.textDirection,   //textDirection水平方向上子控件的起始位置
        this.verticalDirection = VerticalDirection.down,  //垂直方向上子控件的其实位置
        List<Widget> children = const <Widget>[],   //要显示的子控件集合
      })
    
    

    使用🌰(数据模型代码没贴出):

    // MARK - Option Alert
    Widget _buildOptionView(Dispatch dispatch, OptionState state) {
      return Container(
        decoration: const BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.only(
              topLeft: (Radius.circular(16)), topRight: (Radius.circular(16))),
        ),
        child: Column(
          children: [
            _buildAppbar(),
            Expanded(
              child: ListView.builder(
                  itemCount: state.optionTitles.length,
                  itemBuilder: (BuildContext context, int index) {
                    return _buildOptionCard(state, index);
                  }),
            ),
            MaterialButton(
              height: 50,
              minWidth: Screen.width - 32,
              shape: const RoundedRectangleBorder(
                side: BorderSide.none,
                borderRadius: BorderRadius.all(Radius.circular(25)),
              ),
              onPressed: () {
                dispatch(OptionActionCreator.onCompleteAction());
              },
              color: const Color.fromRGBO(51, 55, 88, 1),
              child: const Text(
                '完成',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 16,
                ),
              ),
            ),
            const SizedBox(height: 24),
          ],
        ),
      );
    }
    
    Widget _buildAppbar() {
      return Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          SizedBox(
            width: 60,
            child: MaterialButton(
              onPressed: () {
                _dispatch(OptionActionCreator.onResetAction());
              },
              child: const Text(
                '重置',
                style: TextStyle(fontSize: 14),
              ),
            ),
          ),
          const Text(
            '全部筛选',
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
          SizedBox(
            width: 60,
            child: MaterialButton(
              onPressed: () {
                // SmartDialog.dismiss();
                Navigator.of(_viewService.context).pop();
              },
              child: Container(
                margin: const EdgeInsets.only(left: 16),
                child: const Image(
                  image: AssetImage('images/close@3x.png'),
                  width: 12,
                  height: 12,
                ),
              ),
            ),
          ),
        ],
      );
    }
    
    Widget _buildOptionCard(OptionState state, int index) {
      String key = state.optionTitles[index];
      List optionItems = state.optionInfo[key];
    
      OptionModel model = state.options[index];
    
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            margin: const EdgeInsets.only(left: 16),
            child: Text(
              key,
              textAlign: TextAlign.left,
              style: const TextStyle(
                fontSize: 14,
              ),
            ),
          ),
          Container(
            margin: const EdgeInsets.only(left: 16),
            child: Wrap(
              spacing: 8,
              children: List.generate(optionItems.length, (itemIndex) {
                return buildChoiceButton(model, index, itemIndex);
              }).toList(),
            ),
          ),
          const SizedBox(height: 20),
        ],
      );
    }
    
    Widget buildChoiceButton(OptionModel model, int optionIndex, int itemIndex) {
      bool selected = false;
    
      if (model.single) {
        selected = model.selectedIndex == itemIndex;
      } else {
        selected = model.selectedIndexes.contains(itemIndex);
      }
    
      Color bgColor = selected ? model.selectedBgColor : model.normalBgColor;
      Color textColor = selected ? model.selectedTextColor : model.normalTextColor;
    
      BorderSide selectedSide =
          BorderSide(color: model.selectedTextColor, width: 1);
    
      return MaterialButton(
        onPressed: () {
          // Update state
          _state.optionSelectedIndex = optionIndex;
          _state.optionItemSelectedIndex = itemIndex;
    
          _dispatch(OptionActionCreator.onClickOptionCardItem());
        },
        height: 32,
        minWidth: 105,
        color: bgColor,
        shape: RoundedRectangleBorder(
          side: selected ? selectedSide : BorderSide.none,
          borderRadius: const BorderRadius.all(Radius.circular(16)),
        ),
        child: Text(
          model.optionItems[itemIndex],
          style: TextStyle(fontSize: 14, color: textColor),
        ),
      );
    }
    
    

    类似效果如图:

    Screenshot_1637909919.png

    相关文章

      网友评论

          本文标题:flutter 中如何使用Wrap实现流布局

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