【问题标题】:How to set the width and height of a button in Flutter?如何在 Flutter 中设置按钮的宽度和高度?
【发布时间】:2018-10-21 22:34:33
【问题描述】:

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

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

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

【问题讨论】:

  • 请注意,如果您决定让您的应用程序易于访问(提供更大的字体大小)或多语言(某些语言比其他语言更冗长),那么具有固定宽度的 UI 设计可能会让您头疼。
  • 在灵活模式中,raisebutton 不会在 minWidth 处停止。我尝试了 SizedBox,但没有为凸起按钮保持最小宽度
  • 对于那些试图解决多语言问题的人,我最终在按钮周围使用了一个 ConstrainedBox,并将约束设置为BoxConstraints.tightFor(height: 50)。这会设置一个高度,但允许按钮水平扩展以适应不同的文本长度。

标签: flutter flutter-layout


【解决方案1】:

如文档中所述here

凸起按钮的最小尺寸为 88.0 x 36.0 被 ButtonTheme 覆盖。

你可以这样做

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

【讨论】:

  • 有没有类似“match_parent”的东西??
  • 你可以使用width:MediaQuery.of(context).size.widthwidth:double.infinity
  • 只需将其包装在展开的小部件中
  • 它删除所有基本按钮主题值
  • 对于 Flutter 2 按钮(文本、高架、轮廓等请参阅下面的答案,因为此答案似乎不再适用于它们。
【解决方案2】:

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(...)
)

【讨论】:

  • 有趣的解决方案。我想我们应该使用边距在两侧留出一些空白空间。
  • 在这种情况下,您应该使用Container 而不是SizedBox
  • @CopsOnRoad SizedBox 创建一个固定大小的盒子。与 Container 小部件不同,Sized Box 没有颜色或装饰参数。所以,如果只需要设置宽度,那么SizedBox就更清晰了。您也可以查看此答案以查找更多信息stackoverflow.com/questions/55716322
  • @HasanEl-Hefnawy 我知道这就是我使用大小盒子的原因。但是有人要求保证金,我用容器解决方案回复他
  • @CopsOnRoad,你是对的,我错了。需要明确的是,这在列中起作用:它放大按钮以占据列的所有宽度。我无法修改我原来的评论,所以我删除了它以避免误导。
【解决方案3】:

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

通常我们有 2 个用例:

  • 小部件的子级定义了一个约束。父大小本身基于该信息。例如:Padding,它采用子约束并增加它。
  • 父级对其子级实施约束。例如:SizedBox,还有Column 在拉伸模式下,...

RaisedButton 是第一种情况。这意味着它是定义自己的高度/宽度的按钮。而且,根据材质规则,凸起的按钮大小是固定的。

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


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

【讨论】:

  • 我在哪里可以阅读所有材料规则以了解情况 1 何时适用以及情况 2 何时适用?
【解决方案4】:

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

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

【讨论】:

  • 使用 minWidth 并不能完全回答设置宽度的问题。在这里使用 Wrap 父小部件可能会有所帮助。
  • 这对于获得紧密包裹标签的较小按钮来说是完美的。
【解决方案5】:

Flutter 2.0 中,RaisedButton 已被弃用,取而代之的是 ElevatedButton

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

输出

完整代码

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

【讨论】:

    【解决方案6】:

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

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

    【讨论】:

    • “扩展的你” - 你的意思是扩展的小部件?
    • flex 默认值为1,无需指定。
    【解决方案7】:

    我更喜欢用匹配父级制作 Raise 按钮​​的方法是用 Container 包裹它。 下面是示例代码。

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

    【讨论】:

      【解决方案8】:

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

        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 应用类似的解决方案。

      【讨论】:

      • 如果答案是“MediaQuery”,您问错了问题。您几乎总是希望 LayoutBuilder 让您的空间可用,而不是 MediaQuery。
      【解决方案9】:

      这段代码将帮助您更好地解决您的问题,因为我们不能直接为 RaisedButton 指定宽度,我们可以为其子项指定宽度

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

      【讨论】:

      • 另外,如果您希望按钮占屏幕的 80%,例如,您可以width * 0.8
      【解决方案10】:

      只需使用FractionallySizedBox,其中widthFactorheightFactor 定义应用程序/父级大小的百分比。

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

      【讨论】:

        【解决方案11】:

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

        【讨论】:

        • "新按钮 TextButton、ElevatedButton、OutlinedButton 等将以不同的方式进行更改。" -- 你凭什么这么说,因为你不需要ConstrainedBox,因为Container(width, height) 肯定在使用新按钮
        • 我指的是公认的答案:解决方案 (minWidth: 200.0, height: 100.0, ) 不适用于新的按钮类型。您的解决方案可能也有效。
        • 为什么不呢?该答案已过时,我为更新的颤振版本提供了不同的方法。我什至在该答案下发表评论,指出新工具并提供了合适的解决方案。
        【解决方案12】:

        如果您想全局更改所有RaisedButtons 的高度和最小宽度,那么您可以在MaterialApp 中覆盖ThemeData

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

        【讨论】:

          【解决方案13】:

          将 RaisedButton 包裹在 Container 内并为 Container Widget 指定宽度。

          例如

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

          【讨论】:

            【解决方案14】:

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

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

            【讨论】:

              【解决方案15】:

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

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

              您可以通过使用 GestureDetector 来使用您想要的任何形状作为按钮,GestureDetector 是一个小部件并在子属性下接受另一个小部件。 就像这里的另一个例子一样

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

              【讨论】:

                【解决方案16】:

                如果按钮放置在Flex 小部件中(包括RowColumn),您可以使用Expanded Widget 包装它以填充可用空间。

                【讨论】:

                • Expanded 只有在你父母支持你的情况下才能使用。
                • Expanded 应该用于像RowColumn 这样的多子小部件。
                【解决方案17】:

                这对我有用。 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: () {},
                    ),
                  ),
                ),
                

                【讨论】:

                  【解决方案18】:

                  我们使用 RowColumnExpandedContainer 以及使用示例 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'),
                                            ),
                                          ),
                                        ),
                                      ),
                                    ],
                                  ),
                                ],
                              ),
                            ),
                  

                  【讨论】:

                    【解决方案19】:
                    SizedBox(
                      width: double.infinity,
                      child: ElevatedButton(
                        child: Text("FULL WIDTH"),
                        onPressed: () {},
                      ),
                    ),
                    

                    使用 ElevatedButton,因为 RaisedButton 已被弃用

                    【讨论】:

                      【解决方案20】:

                      在我的例子中,我使用边距来改变大小:

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

                      【讨论】:

                        【解决方案21】:

                        试试看

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

                        【讨论】:

                          【解决方案22】:

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

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

                          【讨论】:

                            【解决方案23】:

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

                            crossAxisAlignment: CrossAxisAlignment.stretch

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

                            【讨论】:

                              【解决方案24】:

                              全宽按钮的短而甜的解决方案:

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

                              【讨论】:

                              • 既不短也不甜。您只是在树层次结构中添加冗余小部件。为什么不在SizedBox 中简单地使用double.infinity?那会更“短”和“甜”。
                              • 该示例不使用冗余小部件。如果您的意思是您可以使用不同的小部件实现相同的结果,那么我会说这是不同的。无论如何,我不知道我们可以在没有固定大小的情况下使用 SizedBox。调查后我发现SizedBox.expand() 可能比使用 double.infinity 更可取。
                              • SizedBox.expand 本质上是一个SizedBox,其中widthheight 设置为double.infinity。所以,即使你的SizedBox.expand 也不会回答关于width 而不是width + height 的OP 问题。
                              • 反正题主是关于设置按钮宽度的。我认为我的回答对像我这样来这里寻找使按钮全宽的方法的其他人有所帮助。
                              • 您的回答添加了不必要的小部件来完成更简单的任务。这可能对性能不利。
                              猜你喜欢
                              • 2022-12-04
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2015-06-24
                              • 1970-01-01
                              • 1970-01-01
                              • 2011-04-25
                              • 2020-12-17
                              相关资源
                              最近更新 更多