Home > Back-end >  Stop wrap widget from expanding child widgets - Flutter
Stop wrap widget from expanding child widgets - Flutter

Time:10-20

I have my custom Button widget in a container which width is defined by the width of its content (it can't be static). When I put that widget in a wrap widget it expands my custom Button to screen width, but if I put it in a row it wraps correctly and I can't figure out how to maintain wanted width of children inside the wrap widget. Here is the code below:

My Custom Button Widget:

class Button extends StatefulWidget {
  final String imageAsset;
  final String btnText;
  final Color colorBegin;
  final Color colorEnd;

  const Button({Key? key, required this.imageAsset, required this.btnText, required this.colorBegin, required this.colorEnd}) : super(key: key);

  @override
  State<Button> createState() => _ButtonState();
}

class _ButtonState extends State<Button> {
  Variables variables = Variables();
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [widget.colorBegin, widget.colorEnd]
        ),
        borderRadius: BorderRadius.all(Radius.circular(variables.radius(context, 16)))
      ),
      child: Row(
        children: [
          Image.asset(
            widget.imageAsset,
            height: variables.height(context, 5),
            width: variables.height(context, 5),
          ),
          SizedBox(width: variables.width(context, 3)),
          Text(
              widget.btnText,
            style: TextStyle(
              fontFamily: 'LeagueSpartanRegular',
              fontSize: variables.height(context, 2.5),
              color: Color(0xFF0B182A),
            ),
          ),
          SizedBox(width: variables.width(context, 4)),
        ],
      ),
    );
  }
}

My wrap widget:

class _ButtonListState extends State<ButtonList> {
  @override
  Widget build(BuildContext context) {
    return Wrap(
      alignment: WrapAlignment.center,
        runSpacing: 20,
        children: const [
          Button(
            btnText: 'Little Friend',
            imageAsset: 'assets/images/icon_little_friend.png',
            colorBegin: Color(0xFFb3d7a4),
            colorEnd: Color(0xFFb0caaa),
          ),
          Button(
            btnText: 'Little Friend',
            imageAsset: 'assets/images/icon_little_friend.png',
            colorBegin: Color(0xFFb3d7a4),
            colorEnd: Color(0xFFb0caaa),
          ),
          Button(
            btnText: 'Little Friend',
            imageAsset: 'assets/images/icon_little_friend.png',
            colorBegin: Color(0xFFb3d7a4),
            colorEnd: Color(0xFFb0caaa),
          ),
          Button(
            btnText: 'Little Friend',
            imageAsset: 'assets/images/icon_little_friend.png',
            colorBegin: Color(0xFFb3d7a4),
            colorEnd: Color(0xFFb0caaa),
          ),
        ],
    );
  }
}

And my home screen:

class _HomeWidgetState extends State<HomeWidget> {
  Variables variables = Variables();
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(top: variables.height(context, 7)),
      decoration: const BoxDecoration(
        image: DecorationImage(
          image: AssetImage("assets/images/bg_main.png"),
          fit: BoxFit.cover,
        ),
      ),
      child: Column(
        children: [
          TextCatalogue(),
          SizedBox(height: variables.height(context, 4)),
          Expanded(child: Stack(
              children: [
                WhiteBackgroundHome(),
                ButtonList(),
              ]
          )
          ),
        ],
      ),
    );
  }
}

Problem Here is the problem

This is the result when I replace wrap with row, the children aren't expanded

image I tried placing it out of the expanded widget on the home screen, tried deleting everything on the home screen and returning only the wrap widget still get the same result. It fixes the problem if I define the width of my custom button widget, but that is not the solution because the buttons will have different width depending on the text inside.

CodePudding user response:

You want the width of each button to be the sum of widths of its children. In your Button widget's build function. Add mainAxisSize: MainAxisSize.min to the Row widget.

From the docs:

The width of the Row is determined by the mainAxisSize property. If the mainAxisSize property is MainAxisSize.max, then the width of the Row is the max width of the incoming constraints. If the mainAxisSize property is MainAxisSize.min, then the width of the Row is the sum of widths of the children (subject to the incoming constraints).

//...
child: Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Image.asset(
      widget.imageAsset,
      height: variables.height(context, 5),
      width: variables.height(context, 5),
    ),
//...

CodePudding user response:

Try adding this line for your Button widget.

class _ButtonState extends State<Button> {
  Variables variables = Variables();
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [widget.colorBegin, widget.colorEnd]
        ),
        borderRadius: BorderRadius.all(Radius.circular(variables.radius(context, 16)))
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,   //                    
        children: [
          Image.asset(
            widget.imageAsset,
            height: variables.height(context, 5),
            width: variables.height(context, 5),
          ),
          SizedBox(width: variables.width(context, 3)),
          Text(
              widget.btnText,
            style: TextStyle(
              fontFamily: 'LeagueSpartanRegular',
              fontSize: variables.height(context, 2.5),
              color: Color(0xFF0B182A),
            ),
          ),
          SizedBox(width: variables.width(context, 4)),
        ],
      ),
    );
  }
}
  • Related