如何在Flutter中设置按钮的宽度和高度?

How to set the width and height of a button in Flutter?

我看到无法在 Flutter 中设置 ElevatedButton 的宽度。如果我理解的很好,我应该把ElevatedButton变成SizedBox。然后我将能够设置框的宽度或高度。这是正确的吗?还有其他方法吗?

在每个按钮周围创建一个 SizedBox 有点乏味,所以我想知道他们为什么选择这样做。我很确定他们这样做有充分的理由,但我没有看到。 脚手架对于初学者来说很难阅读和构建。

new SizedBox(
  width: 200.0,
  height: 100.0,
  child: ElevatedButton(
    child: Text('Blabla blablablablablablabla bla bla bla'),
    onPressed: _onButtonPressed,
  ),
),

那是因为 flutter 与大小无关。这是关于约束的。

通常我们有 2 个用例:

  • 小部件的子项定义了约束。父尺寸本身基于该信息。例如:Padding,采用子约束并增加它。
  • 父项对其子项强制执行约束。例如:SizedBox,而且在 strech 模式下 Column,...

RaisedButton是第一种情况。这意味着它是定义自己的 height/width 的按钮。并且,根据material规则,凸起的按钮大小是固定的。

您不希望出现这种行为,因此您可以使用第二种类型的小部件来覆盖按钮约束。


无论如何,如果您非常需要它,请考虑创建一个新的小部件来为您完成这项工作。或使用 MaterialButton,其高度为 属性。

我建议使用 MaterialButton,你可以这样做:

MaterialButton( 
 height: 40.0, 
 minWidth: 70.0, 
 color: Theme.of(context).primaryColor, 
 textColor: Colors.white, 
 child: new Text("push"), 
 onPressed: () => {}, 
 splashColor: Colors.redAccent,
)

如文档中所述here

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

你可以这样做

ButtonTheme(
  minWidth: 200.0,
  height: 100.0,
  child: RaisedButton(
    onPressed: () {},
    child: Text("test"),
  ),
);

如果按钮放置在 Flex 小部件中(包括 RowColumn),您可以使用 Expanded Widget 将其包装以填充可用的 space.

match_parent(全宽):

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

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

具体宽度:

SizedBox(
  width: 100, // <-- Your width
  height: 50, // <-- Your height
  child: ElevatedButton(...)
)

这段代码可以帮助您更好地解决问题,因为我们不能直接给RaisedButton指定宽度,我们可以给它的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,
    );

您需要使用扩展小部件。但是,如果您的按钮在一列上,则扩展小部件会填充该列的其余部分。因此,您需要将 Expanded Widget 括在一行中。

Row(children: <Widget>[
Expanded(
  flex: 1,
  child: RaisedButton(
    child: Text("Your Text"),
      onPressed: _submitForm,
    ),
  ),),])

如果您想全局更改所有 RaisedButton 的高度和最小宽度,那么您可以在 MaterialApp:

中覆盖 ThemeData
 @override
  Widget build(BuildContext context) {
    return MaterialApp(
       ...
       theme: ThemeData(
       ...
       buttonTheme: ButtonThemeData(
          height: 46,
          minWidth: 100,
       ),
    ));
  }

您可以按照他们在评论中所说的那样做,或者您可以节省精力并使用 RawMaterialButton 。它拥有一切,您可以将边框更改为圆形 以及许多其他属性。 ex 形状(增加半径以获得更圆的形状)

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

并且您可以使用 GestureDetector 将任何形状用作按钮,GestureDetector 是一个小部件并在 child 属性下接受另一个小部件。 就像这里的另一个例子

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,),
              ),
              )
)

我的首选方法是使用 Container 包装 Raise button 与 match parent。 下面是示例代码。

Container(
          width: double.infinity,
          child: RaisedButton(
                 onPressed: () {},
                 color: Colors.deepPurpleAccent[100],
                 child: Text(
                        "Continue",
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                  )

将 RaisedButton 包裹在 Container 中,并赋予 Container Widget 宽度。

例如

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

您可以创建全局方法,例如在整个应用程序中使用的按钮。它将根据容器内的文本长度调整大小。 FittedBox widget 用于让widget 适合里面的child。

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

如果你想要特定宽度和高度的按钮,你可以使用 RawMaterialButton 的约束 属性 来给出按钮的最小最大宽度和高度

constraints: BoxConstraints(minHeight: 45.0,maxHeight:60.0,minWidth:20.0,maxWidth:150.0),

在我的例子中,我使用边距来改变尺寸:

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"),
        ),
      ),

使用媒体查询为您的解决方案明智地使用宽度,这将运行对小屏幕和大屏幕相同

  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
            ),
          )

您也可以对 SizeBox 应用类似的解决方案。

只需使用 FractionallySizedBox,其中 widthFactor & heightFactor 定义 app/parent 大小的百分比。

FractionallySizedBox(
widthFactor: 0.8,   //means 80% of app width
child: RaisedButton(
  onPressed: () {},
  child: Text(
    "Your Text",
    style: TextStyle(color: Colors.white),
  ),
  color: Colors.red,
)),

试试看

Expanded(   
  child: RaisedButton(
    onPressed: _onButtonPressed,
    child: Text('Button1')
  )  
)

如果您不想删除所有按钮主题设置。




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

全宽按钮的简短而巧妙的解决方案:

Row(
  children: [
    Expanded(
      child: ElevatedButton(...),
    ),
  ],
)

如果您在 Column() 中有一个按钮并希望该按钮具有最大宽度,请设置:

crossAxisAlignment: CrossAxisAlignment.stretch

在您的“专栏”小部件中。现在此 Column() 下的所有内容都将具有最大可用宽度

这对我有用。 Container 提供高度,FractionallySizedBox 提供 RaisedButton 的宽度。

Container(
  height: 50.0, //Provides height for the RaisedButton
  child: FractionallySizedBox(
    widthFactor: 0.7, ////Provides 70% width for the RaisedButton
    child: RaisedButton(
      onPressed: () {},
    ),
  ),
),

我们使用扩展容器 和要使用的元素示例 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'),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),

新按钮 TextButton、ElevatedButton、OutlinedButton 等 将以不同的方式进行更改。

我发现的一种方法来自this article:你需要在按钮周围“收紧”一个约束框。

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: () {},
            ),
          ),
        ));
  }

随着 Flutter 2.0 RaisedButton 被弃用并被 ElevatedButton 取代。

考虑到这一点,更简洁的方法ElevatedButton 提供自定义大小是 minimumSize 属性 of ElevatedButton 小部件。

输出

完整代码

          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'),
          )

注意: 另外请记住,可以在 TextButtonOutlinedButton 等新小部件中使用相同的方法,使用 TextButton.styleFrom(minimumSize: Size(100, 40))OutlinedButton.styleFrom(minimumSize: Size(100, 40))分别.

SizedBox(
  width: double.infinity,
  child: ElevatedButton(
    child: Text("FULL WIDTH"),
    onPressed: () {},
  ),
),

使用 ElevatedButton,因为 RaisedButton 已弃用

试试 Container,我想我们会有更多的控制权。

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"),
          ),

        ),

我一直在努力解决这个问题并发现我的问题所在:我在 ListView 中定义了所有按钮。不管我做了什么,按钮的宽度始终是屏幕的宽度。我用 Column 替换了 ListView,瞧 - 突然间我可以控制按钮宽度了。

使用带有宽度和高度参数的 SizeBox

尺寸框( 宽度:double.infinity, 身高:55.0, child:提升按钮( ..... ), );