Home > OS >  Text widget FontWeight bold property makes widget getting wider
Text widget FontWeight bold property makes widget getting wider

Time:10-30

I have a Wrap widget that wraps three InkWell. Each InkWell contains a Text widget. They are meant to be like TabBars to filter my ListView data. When a tab is selected, its FontWeight property is set to bold (w700), when it's not selected, it becomes normal weight.

Here is my code:

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);
                        });
                      }
                    },
                  )
                ],
              ),
            ),

Problem is whenever I move from first tab Semua to other tab, the first tab width size is getting decreased (wrap content).

Example: Before: Semua tab

After: Kolam Kendala tab

It is not clear to see with screenshots. But what actually happening is Kolam Normal tab moved a little to left because Semua tab is getting smaller.

CodePudding user response:

This requires you to specify a width to your Container. But as you probably want a way where the Container always follows the length of text, the code below will solve your issue.

The solution requires you to use the TextPainter to calculate the width that the text would require post build, and we use the style of the higher fontWeight to take the max width and make a constant for both weights (as seen in the style provided to the span in the LayoutBuilder). To use this calculated value almost immediately, we use the LayoutBuilder

Also its not good practice to repeat similar widgets as you've done in your question, but instead to create a function to reproduce them with different variables (also shown in code)

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);
          });
        }
      },
    );
  }
  • Related