How to have a Flutter button be as wide as possible up to a maximum width?

Viewed 3689

In the following layout, I'd like the button to be able to grow to be as wide as possible on the screen, up to a maximum width. I've tried the following, which doesn't work (the button is always as wide as possible):

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                TextFormField(),
                TextFormField(),
                ConstrainedBox(
                  constraints: BoxConstraints(maxWidth: 200),
                  child: RaisedButton(child: Text("button"), onPressed: () {}),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

To expand on the layout I'm looking for: the button must be the same width as the smaller of the following two quantities: 1) the width of the screen, 2) a given fixed maximum width.

Example scenarios:

A) the screen is 1000 pixels wide, and the given fixed maximum width is 600 pixels, then the button will be 600 pixels wide.

B) the screen is 400 pixels wide, and the given fixed maximum width is 600 pixels, then the button will be 400 pixels wide.

4 Answers

The solution is pretty simple, simply wrap your ConstrainedBox in Align and instead of using maxWidth use minWidth.

Align(
  child: ConstrainedBox(
    constraints: BoxConstraints(minWidth: 200),
    child: RaisedButton(child: Text("button"), onPressed: () {}),
  ),
)

Output:

  • If screen width > 200, button takes up 200 width

  • If screen width < 200, button takes up screen width

You can remove crossAxisAlignment: CrossAxisAlignment.stretch, because TextFormField is stretching anyway. This code will make the button width to be of a max width size, but no bigger than screen width:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          body: SafeArea(
            child: Center(
              child: Column(
                children: [
                  TextFormField(),
                  TextFormField(),
                  Container(
                    width: 200,
                    child: RaisedButton(
                      onPressed: () {},
                      child: Text('button'),
                    ),
                  ),
                  Container(
                    width: 200,
                    child: RaisedButton(
                      onPressed: () {},
                      child: Text(
                        'Button with long text asf sadf sdf as df s df as '
                        'dfas dfsd f asfauhiusg isdugfisudgfi asudgk usgkdu'
                        'ksdfhk sudfhk sudhfk',
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      );
}

You can put the RaisedButton in a Row:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                TextFormField(),
                TextFormField(),
                ConstrainedBox(
                  constraints: BoxConstraints(maxWidth: 250),
                  child: Row(
                    children: <Widget>[
                      Expanded(
                        child: RaisedButton(child: Text('test')),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

The Row will create a horizontal row, and the RaisedButton widget will only take as much room as its own size.

first wrap with container and add width to infinity to be responsive:

Container(
  width: double.infinity,
  child: ElevatedButton(
  child: Text("button"), 
  onPressed: (){}
),
),

you can add padding too.. known that RaisedButton is deprecated and migrated to ElevatedButton..

Related