Widget for Week: Button

作者: yanftch | 来源:发表于2019-09-30 13:49 被阅读0次

Flutter 中 Button 的使用也非常简单。
Flutter 中的 button 都是 MaterialButton ,这个是基类,所以常见的都是基于他衍生的,官方为我们提供了几个常用的 button,[FlatButton],[OutlineButton],[RaisedButton],下面就一一介绍,并例举一些常用的 case 的样式处理。


image.png

本文基于源码 1.10.2

  • RaisedButton :凸起的按钮,其实就是Android中的Material Design风格的Button ,继承自MaterialButton
  • FlatButton :扁平化的按钮,继承自MaterialButton
  • OutlineButton :带边框的按钮,继承自MaterialButton,其实就是设置了 shape 的 RaisedButton
  • IconButton :图标按钮,继承自StatelessWidget,其实等同于上边的 Button 设置 child 为 Icon

先来看一下 MaterialButton 的构造函数,属性是蛮多的。。。从头说起。

const MaterialButton({
    Key key,
    @required this.onPressed,
    this.onHighlightChanged,
    this.textTheme,
    this.textColor,
    this.disabledTextColor,
    this.color,
    this.disabledColor,
    this.focusColor,
    this.hoverColor,
    this.highlightColor,
    this.splashColor,
    this.colorBrightness,
    this.elevation,
    this.focusElevation,
    this.hoverElevation,
    this.highlightElevation,
    this.disabledElevation,
    this.padding,
    this.shape,
    this.clipBehavior = Clip.none,
    this.focusNode,
    this.autofocus = false,
    this.materialTapTargetSize,
    this.animationDuration,
    this.minWidth,
    this.height,
    this.child,
  })
属性 值类型 说明
onPressed VoidCallback 必填参数,按下回调,设置为 null 则表示禁用,会启用禁用的样式
child Widget Button 上要显示的组件
textColor Color 组件的颜色,比如child 为 Text 时就是设置了 Text 的字体颜色
color Color button 的颜色
disabledColor Color 按钮禁用时候的颜色
disabledTextColor Color 按钮禁用的时候的child 颜色
splashColor Color 水波纹颜色
highlightColor Color 长按时按钮的颜色
elevation double 阴影的范围大小,值越大阴影范围越大
padding EdgeInsetsGeometry 内边距
shape ShapeBorder 设置形状
minWidth double 最小宽度
height double 高度

经过上述属性,基本上就能搭配出来你想要的任何的按钮样式了。

RaisedButton 和 FlatButton 都是直接继承 MaterialButton,所以默认使用的样式大同小异,唯一区别就是 FlatButton扁平化,没有凸起的背景色,所以比较适合给 Text 设置点击事件的。

属性介绍完毕,相信大家都有个印象,对比自己的 Android 或者 iOS 经验,也都能脑补出来样式。。。
下边就说一下开发中常用的一些样式。

padding

很多时候,按钮中间的文字,是需要给一点距离的,文字距离上下左右都有一定边距,此时就需要用到 padding 属性,如下代码就是给 Text 四周设置了 20 的边距,距离按钮边框,当然你也可以用EdgeInsets.only()给具体的某一个(几个)方向设置边距,使用EdgeInsets.symmetric()给水平或者垂直方向设置边距。

 RaisedButton(
              onPressed: () {
                _showSnackBar("RaisedButton 设置内边距20");
              },
              child: Text("RaisedButton 设置内边距20"),
              padding: const EdgeInsets.all(20),
            ),

shape

shape 的值是 ShapeBorder ,抽象类,他有几个常见的实现类

  • BeveledRectangleBorder 带斜角的长方形边框
  • CircleBorder 圆形边框
  • RoundedRectangleBorder 圆角矩形
  • StadiumBorder 两端是半圆的边框

对应的都要两个属性:slide ,borderRadius

圆角矩形
如下代码可实现圆角矩形的边框形状,当然了如果你要是想实现 iOS 样式的大圆角的按钮,只需要把 Radius 的值设置的大一点就行了。

RaisedButton(
              onPressed: () {},
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(10)),
              ),
              child: Text(
                "RaisedButton 圆角背景(小)",
                style: TextStyle(fontSize: 10),
              ),
            ),

iOS 样式 按钮
在 IOS 设备上,按钮都是两头半圆样式的,那么就可以简单的实现,两种方案:
1.给RoundedRectangleBorder 的 Radius 设置的超级大
2.直接使用 StadiumBorder()设置为 shape

RaisedButton(
              onPressed: () {},
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(300)),
              ),
              child: Text(
                "RaisedButton 圆角背景(iOS 样式)",
                style: TextStyle(fontSize: 10),
              ),
            ),
RaisedButton(
              onPressed: () {},
              shape: StadiumBorder(),
              child: Text(
                "StadiumBorder 两头半圆",
                style: TextStyle(fontSize: 10),
              ),
            ),

圆形按钮
使用 CircleBorder 可以实现圆形的按钮样式

RaisedButton(
              onPressed: () {},
              padding: const EdgeInsets.all(20),
              shape: CircleBorder(),
              child: Text(
                "圆形样式",
                style: TextStyle(fontSize: 10),
              ),
            ),

斜角的矩形
实现带斜角的矩形,也很简单,直接使用BeveledRectangleBorder就行了,BorderRadius 的值的大小,可以帮助你实现各式各样的斜角。。。
值越大,斜的越厉害,如果设置为 0,就是标准的矩形。

RaisedButton(
              color: Colors.red,
              onPressed: () {},
              shape: BeveledRectangleBorder(
                  borderRadius: BorderRadius.circular(10)),
              child: Text(
                "StadiumBorder 两头半圆",
                style: TextStyle(fontSize: 10),
              ),
            ),

以上实现的一些样式,都是纯色的,单纯的背景色,下边再来实现一些带边框的样式,
BorderShape 的几个实现类里边,都有两个属性:slide 和 borderRadius.
slide 属性可以设置背景色,边框颜色,边框的背景等
borderRadius 就是设置弧形程度。

实现一个红色边框,宽度为 1,白色背景的边框
红色边框用 side 里边的 color 来设置,宽度用 width 设置

 RaisedButton(
              onPressed: () {},
              color: Colors.white,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10),
                  side: BorderSide(color: Colors.red)),
              child: Text("RaisedButton"),
            ),

渐变色按钮
Flutter 中的按钮不支持实现渐变色,所以需要依靠 Container 来帮忙,只需要给按钮的 child套一个 Container,给 Container 设置渐变色就行了。但是需要考虑到处理 button 自带的默认的内边距,一定要记得去掉,不然会很难看。。。

Theme(
              child: RaisedButton(
                onPressed: () {},
                elevation: 0.0,
                color: Colors.white,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10),
                ),
                child: Container(
                  child: Text("RaisedButton"),
                  padding: EdgeInsets.fromLTRB(16, 8, 16, 8),
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10),
                      gradient:
                          LinearGradient(colors: [Colors.green, Colors.red])),
                ),
              ),
              data: ThemeData().copyWith(
                  buttonTheme:
                      ButtonThemeData(padding: const EdgeInsets.all(0))),
            ),

不知道大家有没有发现,按钮在使用过程中,有一个自己的默认的宽高,仔细看看源码,发现是在按钮的主题里边设置了,如下代码,
所以如果你想去掉这个默认值,可以在 Theme 里边进行设置,可以直接在最外层的 MaterialApp 中设置,也可以给按钮嵌套一个 Theme()进行处理。如下代码采用了第二个方案。

ButtonThemeData({
    this.textTheme = ButtonTextTheme.normal,
    this.minWidth = 88.0,
    this.height = 36.0,
    EdgeInsetsGeometry padding,
    ShapeBorder shape,
    this.layoutBehavior = ButtonBarLayoutBehavior.padded,
    this.alignedDropdown = false,
    Color buttonColor,
    Color disabledColor,
    Color focusColor,
    Color hoverColor,
    Color highlightColor,
    Color splashColor,
    this.colorScheme,
    MaterialTapTargetSize materialTapTargetSize,
  })
 Theme(
              child: RaisedButton(
                onPressed: () {},
                color: Colors.white,
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10),
                    side: BorderSide(color: Colors.red, width: 4)),
                child: Text("去掉默认宽高"),
              ),
              data: ThemeData().copyWith(
                  buttonTheme: ButtonThemeData(minWidth: 10, height: 20)),
            ),

带图片/图标的按钮
有时候需要实现一些带有图标的按钮,那么可以用 RaisedButton ,通过 child 嵌套实现,也可以直接使用 IconButton

 RaisedButton(
              onPressed: () {},
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[Icon(Icons.add), Text("带图标")],
              ),
            ),
            SizedBox(width: 10),
            FlatButton(
              onPressed: () {},
              child: Icon(
                Icons.add,
                color: Colors.red,
              ),
            ),
            SizedBox(width: 10),
            IconButton(
              onPressed: () {},
              icon: Icon(
                Icons.add,
                color: Colors.red,
              ),
            ),

OK,今日份 按钮相关内容搞定,后续有遇到其他的样式,再更新进来。。。

源码链接:https://github.com/yanftch/book/blob/master/lib/demo/widgets/w_button.dart

收拾收拾,放假啦~~
预祝小伙伴们假期愉快😸😸😸

相关文章

网友评论

    本文标题:Widget for Week: Button

    本文链接:https://www.haomeiwen.com/subject/qjncpctx.html