如何给Flutter按钮添加边框?

21

我最近开始学习Flutter并且非常喜欢它,但是在UI变化方面遇到了一些问题。感谢任何帮助!

我的目标是得到一个圆形按钮,上面有一个带蓝色背景的图标,并且按钮外面还有一个较深的蓝色边框。已经附上图片。

我的做法是:

  1. 得到一个圆形的蓝色按钮。
  2. 将图标放入按钮中。
  3. 添加边框。

我卡在第三步,因为我不知道如何添加边框,或者是否可能根据我处理问题的方式添加边框。目前特定颜色对我来说不重要,我稍后会更改主题。

这是我目前的代码:

  var messageBtn = new Row(
  children: <Widget>[
    new Padding(
      padding: const EdgeInsets.all(20.0),
      child: new RawMaterialButton(
        onPressed: _messages,
        child: new Padding(
          padding: const EdgeInsets.all(20.0),
          child: new Icon(
            Icons.message,
            size: 30.0,
            color: Colors.white,
          ),
        ),
        shape: new CircleBorder(),
        fillColor: Colors.deepPurple,
      ),
    ),
    new Padding(
        padding: const EdgeInsets.all(8.0),
        child: new Text(
          'Send Messages',
          style: new TextStyle(
            fontSize: 20.0,
          ),
        )),
  ],
);

它产生这个:查看截图

我想要这个:查看第二个截图

6个回答

29

嗨,Kathleen,欢迎您!

您可以通过深入了解构成MaterialButton的小部件来实现所需内容。

首先需要使用Ink小部件。这提供了更灵活的样式设置,可以使用BoxDecoration进行设置。

Ink然后可以包含一个InkWell小部件,该小部件可识别onTap并绘制水波纹效果。默认情况下,水波纹会延伸到包含框的边缘,但您可以使其变成圆形,方法是给InkWell设置一个非常大的borderRadius

以下是您要创建的按钮示例:

Material(
  type: MaterialType.transparency, //Makes it usable on any background color, thanks @IanSmith
  child: Ink(
    decoration: BoxDecoration(
      border: Border.all(color: Colors.indigoAccent, width: 4.0),
      color: Colors.indigo[900],
      shape: BoxShape.circle,
    ),
    child: InkWell(
      //This keeps the splash effect within the circle
      borderRadius: BorderRadius.circular(1000.0), //Something large to ensure a circle
      onTap: _messages,
      child: Padding(
        padding:EdgeInsets.all(20.0),
        child: Icon(
          Icons.message,
          size: 30.0,
          color: Colors.white,
        ),
      ),
    ),
  )
),

这是结果:

Flutter应用程序截图,带有自定义样式按钮


嗯,更新出了问题吗?现在由于BoxDecoration形状的原因,背景变成了白盒子。也许以前从未注意到过... - Ian Smith
@IanSmith,我在最新的Flutter稳定版(1.17)上仍然可以使用它。很乐意帮你看看你的代码。 - Xander
@Xander 这是一个展示问题的示例应用程序:https://pastebin.com/raw/tTCVzRmP - Ian Smith
1
@IanSmith 谢谢,我明白你的意思了。我们应该使用 Material(type: MaterialType.transparency)。我会更新答案。 - Xander

27
只需将IconButton包装在Container中,并将其decoration设置如下:
Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.blue, width: 4),
    color: Colors.yellow,
    shape: BoxShape.circle,
  ),
  child: IconButton(
    iconSize: 56,
    icon: Icon(Icons.check),
    onPressed: () {},
  ),
),

而且你可以用更少的代码得到相同的结果。

Flutter circular button with a border


18

如何使用带有边框的FloatingActionButton:

   FloatingActionButton(
                              mini: false,
                              backgroundColor: Colors.blue.shade900,
                              splashColor: Colors.black,
                              onPressed: () {
                                logOutDialog(context);
                              },
                              hoverElevation: 1.5,
                              shape: StadiumBorder(
                                  side: BorderSide(
                                      color: Colors.blue, width: 4)),
                              elevation: 1.5,
                              child: Icon(
                                Icons.logout,
                                color: _foregroundColor,
                              ),
                            )

1
哇!你的回答真的很有用,可以用来实现底部导航栏效果,其中浮动操作按钮塑造了导航栏! - Miguel Jara
我很高兴 @miguel-jara,请(如果可能的话)录制一个gif文件,然后编辑我的回答! - Esmaeil Ahmadipour

3
在Flutter 2中有TextButton
TextButton(
  style: ButtonStyle(
   side: RedSelectedBorderSide(),
  ),
  child: Text(
    "Button"
  ),
  onPressed: (){}
);

RedSelectedBorderSide() 是什么:

class RedSelectedBorderSide extends MaterialStateBorderSide {
  @override
  BorderSide resolve(Set<MaterialState> states) {
    if (states.contains(MaterialState.selected)) {
      return BorderSide(
        width: 2,
        color: Colors.red,
      ); // 
    }
    return null;// Defer to default value on the theme or widget.
  }
}

1
对于 在style内使用side,并结合MaterialStatePropertyBorderSide
TextButton(
  style: ButtonStyle(
   side: MaterialStateProperty.all(
     BorderSide(width: 1, color: Colors.black),
   ),
  ),
  child: Text(
    "My Button"
  ),
  onPressed: (){}
);

0

我来这里是想了解如何给“CupertinoButton”添加边框。我会在这里发布我的发现。希望能对某些人有所帮助。

结果:

enter image description here

代码:

import 'package:flutter/cupertino.dart';

...

CupertinoButton(
    minSize: 20,
    padding: const EdgeInsets.all(0), // remove button padding
    color: CupertinoColors.white.withOpacity(0),  // use this to make default color to transparent
    child: Container(   // wrap the text/widget using container
      padding: const EdgeInsets.all(10), // add padding
        decoration: BoxDecoration(
          border: Border.all(
            color: const Color.fromARGB(255, 211, 15, 69),
            width: 1,
          ),
          borderRadius: const BorderRadius.all(Radius.circular(10)),  // radius as you wish
        ),
      child: Wrap(
         children: const [
           Icon(CupertinoIcons.videocam_circle_fill, color: CupertinoColors.systemPink,),
           Text(" Upload video", style: TextStyle(color: CupertinoColors.systemPink),)
         ],
       ),
    ),
    onPressed: () {
      // on press action
    },
),

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接