首页 > 解决方案 > 文本小部件 FontWeight 粗体属性使小部件变得更宽

问题描述

我有一个Wrap包含三个InkWell. 每个 InkWell 都包含一个Text小部件。它们旨在像 TabBars 一样过滤我的 ListView 数据。当一个选项卡被选中时,它的FontWeight属性设置为粗体(w700),当它没有被选中时,它变为正常粗细。

这是我的代码:

Align(
              alignment: Alignment.topLeft,
              child: Wrap(
                spacing: 8,
                runSpacing: 8,
                children: [
                  InkWell(
                    borderRadius: BorderRadius.circular(24),
                    child: Container(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 16, vertical: 8),
                      decoration: ShapeDecoration(
                        color: semuaKolamBackgroundColor,
                        shape: RoundedRectangleBorder(
                          side: BorderSide(
                              width: 0.8,
                              style: BorderStyle.solid,
                              color: semuaKolamBorderColor),
                          borderRadius: BorderRadius.all(Radius.circular(24.0)),
                        ),
                      ),
                      child: Text(
                        "Semua",
                        style: TextStyle(
                            fontFamily: "NotoSans", color: semuaKolamTextColor,
                            fontWeight: _selectedJenisKolam == 0 ? FontWeight.w700 : FontWeight.normal),
                      ),
                    ),
                    onTap: () {
                      if (_selectedJenisKolam != 0) {
                        setState(() {
                          _selectedJenisKolam = 0;
                          changeKolamType(0);
                        });
                      }
                    },
                  ),
                  InkWell(
                    borderRadius: BorderRadius.circular(24),
                    child: Container(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 16, vertical: 8),
                      decoration: ShapeDecoration(
                        color: kolamNormalBackgroundColor,
                        shape: RoundedRectangleBorder(
                          side: BorderSide(
                              width: 0.8,
                              style: BorderStyle.solid,
                              color: kolamNormalBorderColor),
                          borderRadius: BorderRadius.all(Radius.circular(24.0)),
                        ),
                      ),
                      child: Text(
                        "Kolam Normal",
                        style: TextStyle(
                            fontFamily: "NotoSans",
                            color: kolamNormalTextColor,
                            fontWeight: _selectedJenisKolam == 1 ? FontWeight.w700 : FontWeight.normal),
                      ),
                    ),
                    onTap: () {
                      if (_selectedJenisKolam != 1) {
                        setState(() {
                          _selectedJenisKolam = 1;
                          changeKolamType(1);
                        });
                      }
                    },
                  ),
                  InkWell(
                    borderRadius: BorderRadius.circular(24),
                    child: Container(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 16, vertical: 8),
                        decoration: ShapeDecoration(
                          color: kolamKendalaBackgroundColor,
                          shape: RoundedRectangleBorder(
                            side: BorderSide(
                                width: 0.8,
                                style: BorderStyle.solid,
                                color: kolamKendalaBorderColor),
                            borderRadius:
                                BorderRadius.all(Radius.circular(24.0)),
                          ),
                        ),
                        child: Text(
                          "Kolam Kendala",
                          style: TextStyle(
                              fontFamily: "NotoSans",
                              color: kolamKendalaTextColor,
                              fontWeight: _selectedJenisKolam == 2 ? FontWeight.w700 : FontWeight.normal),
                        )),
                    onTap: () {
                      if (_selectedJenisKolam != 2) {
                        setState(() {
                          _selectedJenisKolam = 2;
                          changeKolamType(2);
                        });
                      }
                    },
                  )
                ],
              ),
            ),

问题是每当我从第一个选项卡移动Semua到另一个选项卡时,第一个选项卡的宽度尺寸都会减小(换行内容)。

示例:之前:Semua 选项卡

后:Kolam Kendala 选项卡

用截图看不清楚。但实际发生的情况是Kolam Normal选项卡向左移动了一点,因为Semua选项卡越来越小。

标签: flutter

解决方案


这需要您为width您的Container. 但是由于您可能想要一种Container始终遵循文本长度的方式,下面的代码将解决您的问题。

该解决方案要求您使用TextPainter来计算构建后文本所需的宽度,我们使用较高 fontWeight 的样式来获取最大宽度并为两个权重设置一个常量(如提供给spanin LayoutBuilder)。为了几乎立即使用这个计算值,我们使用LayoutBuilder

像您在问题中所做的那样重复类似的小部件也是不好的做法,而是创建一个函数来用不同的变量重现它们(也显示在代码中)

Widget returnNewThing() {
    return Align(
      alignment: Alignment.topLeft,
      child: Wrap(
        spacing: 8,
        runSpacing: 8,
        children: [
          // add the colors and other params into the method if needed
          createInkWell(buttonText: 'Semua', currentIndex: 0),
          createInkWell(buttonText: 'Kolam Normal', currentIndex: 1),
          createInkWell(buttonText: 'Kolam Kendala', currentIndex: 2),
        ],
      ),
    );
  }

  InkWell createInkWell(
      {Color shapeColor = kolanNormalBackgroundColor,
      Color borderColor = kolanNormalBorderColor,
      required String buttonText,
      required int currentIndex,
      Color textColor = kolamNormalTextColor}) {
    return InkWell(
      borderRadius: BorderRadius.circular(24),
      child: LayoutBuilder(builder: (context, size) {
        final span = TextSpan(text: buttonText, style: TextStyle(
            fontFamily: "NotoSans",
            color: textColor,
            fontWeight: FontWeight.w700));
        final tp = TextPainter(
            text: span,
            textDirection: TextDirection.ltr,
            textAlign: TextAlign.start,
            maxLines: 1)
          ..layout(maxWidth: size.maxWidth);
        var widthNeeded = tp.width; //may need to add some padding i.e. + 4
        
        return Container(
          width: widthNeeded,
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
          decoration: ShapeDecoration(
            color: shapeColor,
            shape: RoundedRectangleBorder(
              side: BorderSide(
                  width: 0.8, style: BorderStyle.solid, color: borderColor),
              borderRadius: BorderRadius.all(Radius.circular(24.0)),
            ),
          ),
          child: Text(
            buttonText,
            style: TextStyle(
                fontFamily: "NotoSans",
                color: textColor,
                fontWeight: _selectedJenisKolam == currentIndex
                    ? FontWeight.w700
                    : FontWeight.normal),
          ),
        );
      }), 
      onTap: () {
        if (_selectedJenisKolam != currentIndex) {
          setState(() {
            _selectedJenisKolam = currentIndex;
            changeKolamType(currentIndex);
          });
        }
      },
    );
  }

推荐阅读