244

I have seen that I can't set the width of a ElevatedButton in Flutter. If I have well understood, I should put the ElevatedButton into a SizedBox. I will then be able to set the width or height of the box. Is it correct? Is there another way to do it?

This is a bit tedious to create a SizedBox around every buttons so I'm wondering why they have chosen to do it this way. I'm pretty sure that they have a good reason to do so but I don't see it. The scaffolding is pretty difficult to read and to build for a beginner.

new SizedBox(
  width: 200.0,
  height: 100.0,
  child: ElevatedButton(
    child: Text('Blabla blablablablablablabla bla bla bla'),
    onPressed: _onButtonPressed,
  ),
),
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
OlivierGrenoble
  • 3,803
  • 2
  • 18
  • 25
  • 2
    Read this issue: https://github.com/flutter/flutter/issues/10492 – Blasanka May 11 '18 at 13:57
  • 4
    Please note that a UI design with fixed widths may give you headaches if you'd ever decide to make your app accessible (offer larger font sizes) or multilingual (some languages are more verbose than others). – Ruud Helderman May 11 '18 at 14:42
  • [Check this link](https://androidride.com/flutter-raisedbutton-examples/#height) – Athira Reddy Sep 05 '20 at 04:38
  • In a flexible, the raisebutton does not stop at the minWidth. I tried SizedBox but it didn't work keep a minimum width for the raisedbutton – Golden Lion May 17 '21 at 20:35
  • For those trying to solve the multilingual issue, I ended up using a ConstrainedBox around the button with constraints set to `BoxConstraints.tightFor(height: 50)`. This sets a height but allows the button to expand horizontally for different text lengths. – whla Nov 22 '21 at 02:34
  • Somehow still rocket science to me 4 years later – Wesley Barnes Mar 29 '23 at 08:43

35 Answers35

301

As said in documentation here

Raised buttons have a minimum size of 88.0 by 36.0 which can be overidden with ButtonTheme.

You can do it like that

ButtonTheme(
  minWidth: 200.0,
  height: 100.0,
  child: RaisedButton(
    onPressed: () {},
    child: Text("test"),
  ),
);
Yushin
  • 1,684
  • 3
  • 20
  • 36
Airon Tark
  • 8,900
  • 4
  • 23
  • 19
228

match_parent (Full width):

SizedBox(
  width: double.infinity, // <-- match_parent
  height: double.infinity, // <-- match-parent
  child: ElevatedButton(...)
)

or

SizedBox.expand(
  child: ElevatedButton(...)
) 

Specific width:

SizedBox(
  width: 100, // <-- Your width
  height: 50, // <-- Your height
  child: ElevatedButton(...)
)
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
  • Interesting solution. I guess that we should then use a margin to let some empty space on the sides. – OlivierGrenoble Jan 17 '19 at 08:44
  • In that case you should use `Container` instead of `SizedBox` – CopsOnRoad Mar 15 '19 at 10:21
  • 1
    @CopsOnRoad SizedBox creates a fixed size box. Unlike the Container widget, Sized Box does not have color or decoration parameters. So, if you only need to set the width, in that case, SizedBox is more clearer. You can also check this answer to find more https://stackoverflow.com/questions/55716322 – Hasan El-Hefnawy Jan 11 '21 at 18:46
  • 1
    @HasanEl-Hefnawy I am aware of it which is why I used sized box. But someone was asking for margin and I replied him with Container solution – CopsOnRoad Jan 11 '21 at 18:49
  • @CopsOnRoad, you're right, I was wrong. To be clear, this **works** in a column: it enlarge the button to take all the width of the column. I cannot modify my original comment so I deleted it to avoid misleading. – John Wang Jun 13 '21 at 10:44
  • @JohnWang Ok, but I can still see your comment. I'll delete this one too once you delete your two :) – CopsOnRoad Jun 13 '21 at 11:10
57

With Flutter 2.0 RaisedButton is deprecated and replaced by ElevatedButton.

With that in mind, much more cleaner approach to give custom size to ElevatedButton is minimumSize property of ElevatedButton widget.

Output

enter image description here

Full Code

          ElevatedButton(
            style: ElevatedButton.styleFrom(
              primary: Colors.green,
              onPrimary: Colors.white,
              shadowColor: Colors.greenAccent,
              elevation: 3,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(32.0)),
              minimumSize: Size(100, 40), //////// HERE
            ),
            onPressed: () {},
            child: Text('Hey bro'),
          )

Note: Also keep in mind that same approach can be used in new widgets like TextButton and OutlinedButton using TextButton.styleFrom(minimumSize: Size(100, 40)) and OutlinedButton.styleFrom(minimumSize: Size(100, 40)) respectively.

RuslanBek
  • 1,592
  • 1
  • 14
  • 30
23

That's because flutter is not about size. It's about constraints.

Usually we have 2 use cases :

  • The child of a widget defines a constraint. The parent size itself is based on that information. ex: Padding, which takes the child constraint and increases it.
  • The parent enforce a constraint to its child. ex: SizedBox, but also Column in strech mode, ...

RaisedButton is the first case. Which means it's the button which defines its own height/width. And, according to material rules, the raised button size is fixed.

You don't want that behavior, therefore you can use a widget of the second type to override the button constraints.


Anyway, if you need this a lot, consider either creating a new widget which does the job for you. Or use MaterialButton, which possesses a height property.

Python Steve
  • 61
  • 1
  • 1
  • 13
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
21

I would recommend using a MaterialButton, than you can do it like this:

MaterialButton( 
 height: 40.0, 
 minWidth: 70.0, 
 color: Theme.of(context).primaryColor, 
 textColor: Colors.white, 
 child: new Text("push"), 
 onPressed: () => {}, 
 splashColor: Colors.redAccent,
)
iDecode
  • 22,623
  • 19
  • 99
  • 186
kevinbrink
  • 1,265
  • 8
  • 14
9

You need to use an Expanded Widget. But, if your button is on a column, the Expanded Widget fills the rest of the column. So, you need to enclose the Expanded Widget within a row.

Row(children: <Widget>[
Expanded(
  flex: 1,
  child: RaisedButton(
    child: Text("Your Text"),
      onPressed: _submitForm,
    ),
  ),),])
Elton Morais
  • 91
  • 1
  • 2
8

Use Media Query to use width wisely for your solution which will run the same for small and large screen

  Container(
            width: MediaQuery.of(context).size.width * 0.5, // Will take 50% of screen space
            child: RaisedButton(
              child: Text('Go to screen two'),
              onPressed: () => null
            ),
          )

You can apply a similar solution to SizeBox also.

Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147
  • If the answer is "MediaQuery", you asked the wrong question. You nearly always want LayoutBuilder to get your space available, not MediaQuery. – Randal Schwartz Sep 20 '21 at 22:39
8

The new buttons TextButton, ElevatedButton, OutlinedButton etc. are to be changed in a different way.

One method I found is from this article: you need to "tighten" a constrained box around the button.

Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Kindacode.com'),
        ),
        body: Center(
          child: ConstrainedBox(
            constraints: BoxConstraints.tightFor(width: 300, height: 200),
            child: ElevatedButton(
              child: Text('300 x 200'),
              onPressed: () {},
            ),
          ),
        ));
  }
ForestG
  • 17,538
  • 14
  • 52
  • 86
  • "The new buttons TextButton, ElevatedButton, OutlinedButton etc. are to be changed in a different way." -- On what basis are you saying this because you don't need a `ConstrainedBox` since a `Container(width, height)` is definitely working with *new buttons* – iDecode May 17 '21 at 08:28
  • I was referring to the accepted answer: the solution (`minWidth: 200.0, height: 100.0,` ) is not working with the new button types. Your solution probably works too. – ForestG May 17 '21 at 08:36
  • why not? That answer is outdated, and I provide a different approach for an updated flutter version. I even commented under that answer to indicate the new tools and provided a suitable solution. – ForestG May 17 '21 at 09:29
6

My preferred way to make Raise button with match parent is that wrap it with Container. below is sample code.

Container(
          width: double.infinity,
          child: RaisedButton(
                 onPressed: () {},
                 color: Colors.deepPurpleAccent[100],
                 child: Text(
                        "Continue",
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                  )
Hitesh Dhamshaniya
  • 2,088
  • 2
  • 16
  • 23
6

We can also use ElevatedButton Widget, it have fixedSize property. latest Flutter version

 ElevatedButton(
          onPressed: () {},
          style: ElevatedButton.styleFrom( 
              fixedSize: Size(120, 34), // specify width, height
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(
                20,
              ))),
          child: Text("Search"),
        )

Preview

Preview

5

This piece of code will help you better solve your problem, as we cannot specify width directly to the RaisedButton, we can specify the width to it's child

double width = MediaQuery.of(context).size.width;
var maxWidthChild = SizedBox(
            width: width,
            child: Text(
              StringConfig.acceptButton,
              textAlign: TextAlign.center,
            ));

RaisedButton(
        child: maxWidthChild,
        onPressed: (){},
        color: Colors.white,
    );
Fayaz
  • 1,846
  • 2
  • 16
  • 21
5

Simply use FractionallySizedBox, where widthFactor & heightFactor define the percentage of app/parent size.

FractionallySizedBox(
widthFactor: 0.8,   //means 80% of app width
child: RaisedButton(
  onPressed: () {},
  child: Text(
    "Your Text",
    style: TextStyle(color: Colors.white),
  ),
  color: Colors.red,
)),
BSMP
  • 4,596
  • 8
  • 33
  • 44
Mimu Saha Tishan
  • 2,402
  • 1
  • 21
  • 40
4

You can create global method like for button being used all over the app. It will resize according to the text length inside container. FittedBox widget is used to make widget fit according to the child inside it.

Widget primaryButton(String btnName, {@required Function action}) {
  return FittedBox(
  child: RawMaterialButton(
  fillColor: accentColor,
  splashColor: Colors.black12,
  elevation: 8.0,
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),
  child: Container(
    padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 13.0),
    child: Center(child: Text(btnName, style: TextStyle(fontSize: 18.0))),
  ),
  onPressed: () {
    action();
   },
  ),
 );
}

If you want button of specific width and height you can use constraint property of RawMaterialButton for giving min max width and height of button

constraints: BoxConstraints(minHeight: 45.0,maxHeight:60.0,minWidth:20.0,maxWidth:150.0),
Shikhar Singh
  • 112
  • 1
  • 11
3

If you want globally change the height and the minWidth of all your RaisedButtons, then you can override ThemeData inside your MaterialApp:

 @override
  Widget build(BuildContext context) {
    return MaterialApp(
       ...
       theme: ThemeData(
       ...
       buttonTheme: ButtonThemeData(
          height: 46,
          minWidth: 100,
       ),
    ));
  }
Saeed Masoumi
  • 8,746
  • 7
  • 57
  • 76
3

Wrap RaisedButton inside Container and give width to Container Widget.

e.g

 Container(
 width : 200,
 child : RaisedButton(
         child :YourWidget ,
         onPressed(){}
      ),
    )
2

This worked for me. The Container provides the height and FractionallySizedBox provides the width for the RaisedButton.

Container(
  height: 50.0, //Provides height for the RaisedButton
  child: FractionallySizedBox(
    widthFactor: 0.7, ////Provides 70% width for the RaisedButton
    child: RaisedButton(
      onPressed: () {},
    ),
  ),
),
Raj A
  • 544
  • 9
  • 21
2

Try with Container, I think we will have more control.

ElevatedButton(
          style: ElevatedButton.styleFrom(textStyle: const TextStyle(fontSize: 20)),
          onPressed: () {
            buttonClick();
          },
          child:  Container(
            height: 70,
            width: 200,
            alignment: Alignment.center,
            child: Text("This is test button"),
          ),

        ),
1

If the button is placed in a Flex widget (including Row & Column), you can wrap it using an Expanded Widget to fill the available space.

xinthink
  • 1,460
  • 1
  • 18
  • 22
1

you can do as they say in the comments or you can save the effort and work with RawMaterialButton . which have everything and you can change the border to be circular and alot of other attributes. ex shape(increase the radius to have more circular shape)

shape: new RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),//ex add 1000 instead of 25

and you can use whatever shape you want as a button by using GestureDetector which is a widget and accepts another widget under child attribute. like in the other example here

GestureDetector(
onTap: () {//handle the press action here }
child:Container(

              height: 80,
              width: 80,
              child:new Card(

                color: Colors.blue,
                shape: new RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
                elevation: 0.0,                
              child: Icon(Icons.add,color: Colors.white,),
              ),
              )
)
youssef ali
  • 406
  • 5
  • 11
1

we use Row or Column, Expanded, Container and the element to use example RaisedButton

 body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 10.0),
                ),
                Row(
                  children: <Widget>[
                    Expanded(
                      flex: 2, // we define the width of the button
                      child: Container(
                        // height: 50, we define the height of the button
                        child: Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 10.0),
                          child: RaisedButton(
                            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                            textColor: Colors.white,
                            color: Colors.blue,
                            onPressed: () {
                              // Method to execute
                            },
                            child: Text('Copy'),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      flex: 2, // we define the width of the button
                      child: Container(
                        // height: 50, we define the height of the button
                        child: Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 10.0),
                          child: RaisedButton(
                            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                            textColor: Colors.white,
                            color: Colors.green,
                            onPressed: () {
                              // Method to execute
                            },
                            child: Text('Paste'),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
Jairo Rodriguez
  • 356
  • 2
  • 7
1
SizedBox(
  width: double.infinity,
  child: ElevatedButton(
    child: Text("FULL WIDTH"),
    onPressed: () {},
  ),
),

Use ElevatedButton since RaisedButton is deprecated

inaps
  • 1,516
  • 1
  • 9
  • 14
1

Old question. A lot of answers. I went thru all of them and looked for the answer that provides code for a reusable button that accepts width and height as parameters. As OP specifically noted that it is tedious to wrap every button in a SizedBox.

Not found. So, here is one more answer. Below is a code for the reusable button component with a default size, which also accepts width and height.

class MenuButton extends StatelessWidget {
  final String text;
  final void Function()? onPressed;
  final double width;
  final double height;
  const MenuButton({required this.text, this.onPressed, this.width = 
    200, this.height = 60, super.key}) ;
  @override
  Widget build(BuildContext context) { 
    return SizedBox(
      width: width,
      height: height,
      child: OutlinedButton(
        onPressed: onPressed,
        child: Text(text),
      ),
    );
  }
}

And use it like this:

body: Center(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        const SizedBox(height: 80),
        MenuButton(
            text: 'ПОВТОРИТЬ УРОКИ',
            onPressed: () => context.go("/repeat_lessons")),
        const SizedBox(height: 40),
        MenuButton(
            text: 'СЛЕДУЮЩИЙ УРОК 1',
            onPressed: () => context.pushNamed("lesson", params: {'number': "1"})),
        const SizedBox(height: 40),
        MenuButton(
            text: 'СПИСОК УРОКОВ',
            onPressed: () => context.go("/lesson_list")),

        const SizedBox(height: 40),
        MenuButton(
            text: 'ВЫХОД',
            onPressed: () => print('exit button pressed')),          
      ],
    ),
  ),

enter image description here

Yuriy N.
  • 4,936
  • 2
  • 38
  • 31
0

In my case I used margin to be able to change the size:

Container(


     margin: EdgeInsets.all(10),

    // or margin: EdgeInsets.only(left:10, right:10),



        child: RaisedButton(
          padding: EdgeInsets.all(10),

          shape: RoundedRectangleBorder(borderRadius: 
BorderRadius.circular(20)),
          onPressed: () {},
          child: Text("Button"),
        ),
      ),
Amir Vazirifar
  • 151
  • 2
  • 4
0

If you don't want to remove all the button theme set up.




ButtonTheme.fromButtonThemeData(
  data: Theme.of(context).buttonTheme.copyWith(
                minWidth: 200.0,
                height: 100.0,,
              )
  child: RaisedButton(
    onPressed: () {},
    child: Text("test"),
  ),
);

謝Richard
  • 11
  • 2
0

If you have a button inside a Column() and want the button to take maximum width, set:

crossAxisAlignment: CrossAxisAlignment.stretch

in your Column widget. Now everything under this Column() will have maximum available width

Irfandi D. Vendy
  • 894
  • 12
  • 20
0

I struggled with this problem and found what my problem was: I defined all my buttons inside a ListView. Does not matter what I did, the width of the button was always the width of the screen. I replaces ListView by Column and voila - suddenly I could control the button width.

Zalek Bloom
  • 551
  • 6
  • 13
0

Use SizeBox with width and height parameters

SizedBox( width: double.infinity, height: 55.0, child: ElevatedButton( ..... ), );

Dimal Govinnage
  • 133
  • 1
  • 8
0

In my case(the Button is a child of a horizontal ListView), I had to wrap the button with a padding widget and set right/left padding.

      Padding(
        padding: const EdgeInsets.only(right: 50, left: 50),
        child: ElevatedButton(onPressed: () {}, child: Text("LOGOUT")),
      )

enter image description here

Lojith Vinsuka
  • 906
  • 1
  • 10
  • 8
0

You don't need to use other widget to set the size. You can use minimumSize for ElevatedButton

ElevatedButton(
              style: ElevatedButton.styleFrom(
                      minimumSize: const Size(200, 50),
                      elevation: 0,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(50), // <-- Radius
                      ),
                    ),
                    onPressed: (){},
                    child: const Text("Text", style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),),
                  ),
Sammrafi
  • 399
  • 4
  • 8
0

wrap your ElevatedButton with a Column PLUS add padding for the button for the style:

                          Column(
                            children: [
                              ElevatedButton(
                                  style: TextButton.styleFrom(
                                    backgroundColor: Colors.green,
                                    padding: const EdgeInsets.symmetric(
                                        horizontal: 20 * 1.5, vertical: 20),
                                  ),
                                  onPressed: () {},
                                  child: const Text('text')),],),
0

Approved answer is now deprecated, see docs.

To update code size from theme to all buttons you can do this :

ThemeData(
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ButtonStyle(
        fixedSize:MaterialStateProperty.all<Size?>(Size(200.0, 75.0)),
        textStyle:MaterialStateProperty.all<TextStyle?>(TextStyle(fontSize:30))),
    ),
  )
0

If you want the button to be as narrow as possible, perfectly wrapping its content, i.e. if you want the button to take as much size (width) as its content (rather than the whole row), then wrap the button in a Row (possibly with mainAxisAlignment: MainAxisAlignment.center).

Luke Hutchison
  • 8,186
  • 2
  • 45
  • 40
-1

Try it out

Expanded(   
  child: RaisedButton(
    onPressed: _onButtonPressed,
    child: Text('Button1')
  )  
)
Artem
  • 149
  • 1
  • 2
-1

To set the height and width of Any Button Just Wrap it with SizedBox. you set easily the height and width of any button by Wrape with SizedBox . And if you want to give Space between Two Any Kind of Widgets then you can Used SizedBox and inside the SizedBox you use height .As much as you want to give..

Usman Ali
  • 1
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 05 '22 at 05:40
-3

Short and sweet solution for a full-width button:

Row(
  children: [
    Expanded(
      child: ElevatedButton(...),
    ),
  ],
)
lbrandao
  • 4,144
  • 4
  • 35
  • 43
  • It's neither short nor sweet. You're simply adding redundant widgets in the tree hierarchy. Why not simply use `double.infinity` in a `SizedBox`? That will be much "shorter" and "sweeter". – iDecode Nov 18 '20 at 17:26
  • The example doesn't use redundant widgets. If you mean that you can achieve the same result with different widgets, then I would say that's different. Anyway, I didn't know we could use SizedBox without a fixed size. Looking into it I found `SizedBox.expand()` which would probably be preferable than using double.infinity. – lbrandao Nov 19 '20 at 15:14
  • `SizedBox.expand` is essentially a `SizedBox` with `width` and `height` set to `double.infinity`. So, even your `SizedBox.expand` won't answer the OP question which is about `width` and not `width + height`. – iDecode Nov 19 '20 at 17:08
  • Anyway, the title of the question is about setting the width of a button. I think my answer is helpful to others like me that came here looking for a way to make a button full width. – lbrandao Nov 20 '20 at 03:04
  • Your answer adds unnecessary widgets to do the simpler task. It may be bad for performance. – iDecode Nov 20 '20 at 09:35