美文网首页
Flutter第八章(RaisedButton ,FlatBut

Flutter第八章(RaisedButton ,FlatBut

作者: 一巴掌拍出两坨脂肪 | 来源:发表于2021-04-22 15:03 被阅读0次
    版权声明:本文为作者原创书籍。转载请注明作者和出处,未经授权,严禁私自转载,侵权必究!!!
    情感语录:得之坦然,失之淡然;争其必然,顺其自然!

    欢迎来到本章节,上一章节我们讲了侧边栏的使用,知识点回顾 戳这里 Flutter基础第七章

    本章节将对Flutter中的按钮组件进行介绍,在前面章节的讲解中,其实已经使用到了一些按钮组件,比如 RaisedButtonIconButton 当然在Flutter中可不止这两个按钮,本篇会将常用的按钮组件都进行罗列讲解。

    本章简要:

    1、RaisedButton :Material Design 风格的凸起按钮

    2、FlatButton :扁平化的按钮

    3、OutlineButton:线框按钮

    4、IconButton :图标按钮

    5、ButtonBar:按钮组

    6、FloatingActionButton:浮动按钮

    7、自定义实现(左,上,右,下)的图标按钮

    8、实战 闲鱼app 底部不规则按钮

    按钮组件中的通用属性:

        名称                 属性值
    
        onPressed            按下按钮时触发的回调,接收一个方法,不填或者传 null 表示按钮禁用
                    
                             
        child                文本控件
    
        textColor            文本颜色
    
        color                按钮的颜色
    
        disabledColor        按钮禁用时的颜色
         
        disabledTextColor    按钮禁用时的文本颜色
    
        splashColor          点击按钮时水波纹的颜色
    
        highlightColor       点击(长按)按钮后按钮的颜色
    
        elevation            阴影的范围,值越大阴影范围越大
    
        padding              内边距
    
        shape                设置按钮的形状:
                             shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10),
                             )
                             shape: CircleBorder(
                                side: BorderSide(color: Colors.white)
                             )
    

    一 、RaisedButton :

    RaisedButton 是 Flutter 提供的 Material 风格的按钮,onPressed属性可以传递 null 值,如果传递了 null 值或者不写也为null,整个按钮是不可点击的,disabled 状态(灰色)

    构造函数如下:

     const RaisedButton({
        Key key,
        @required VoidCallback onPressed,
        ValueChanged<bool> onHighlightChanged,
        ButtonTextTheme textTheme,
        Color textColor,
        Color disabledTextColor,
        Color color,
        Color disabledColor,
        Color focusColor,
        Color hoverColor,
        Color highlightColor,
        Color splashColor,
        Brightness colorBrightness,
        double elevation,
        double focusElevation,
        double hoverElevation,
        double highlightElevation,
        double disabledElevation,
        EdgeInsetsGeometry padding,
        ShapeBorder shape,
        Clip clipBehavior,
        FocusNode focusNode,
        MaterialTapTargetSize materialTapTargetSize,
        Duration animationDuration,
        Widget child,
      })
    
    1、普通 Button 及背景颜色控制、阴影控制
      import 'package:flutter/material.dart';
      
      class RaisedButtonPage extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
              home: Scaffold(
                  appBar: AppBar(
                    title: Text("RaisedButtonPage"),
                  ),
                  body:  Column(
                    children: <Widget>[
                      Row(
                        children: <Widget>[
      
                          SizedBox(width: 5),
                          RaisedButton(
                            child: Text('无事件按钮'),
                          ),
                          SizedBox(width: 5),
                          RaisedButton(
                            child: Text('普通按钮'),
                            onPressed: () {},
                          ),
                          SizedBox(width: 5),
                          RaisedButton(
                            color: Colors.pink,
                            textColor: Colors.white,
                            child: Text('颜色按钮'),
                            onPressed: () {},
                          ),
                          SizedBox(width: 5),
                          RaisedButton(
                            elevation: 20,
                            focusElevation: 40,
                            child: Text('阴影按钮'),
                            onPressed: () {},
                          ),
      
                        ],
                      )
      
                    ],
                  )
              )
          );
        }
      }
    

    效果如下:


    RaisedButton1.gif
    2、控制 Button 的宽度和高度

    RaisedButton 本身没有宽度和高度的属性控制,也没有 margin 属性可利用,如果要指定宽度和高度,可以借助 Container 容器,设置 Container 宽度和高度达到控制 RaisedButton 宽高,或者其他能设置宽高的布局widget也可以,如 :SizedBox

      Row(
        children: <Widget>[
    
          SizedBox(width: 5),
    
          Container(
            width: 200,
            height: 50,
            child:   RaisedButton(
              child: Text('宽:200,高:50 按钮'),
              onPressed: () {},
            ),
          ),
    
          SizedBox(width: 5),
          Container(
            width: 220,
            height: 40,
            child:    RaisedButton(
              color: Colors.pink,
              textColor: Colors.white,
              child: Text('宽:220,高:40 按钮'),
              onPressed: () {},
            ),
          )
        ],
      )
    

    效果如下:

    RaisedButton2.gif
    3、宽度自适应按钮

    某些场景下,我们可能期望一个 Button 充满整个屏幕宽度。和宽度高度的控制一样,我们需要借助 Row + Expanded ,或者使用 无穷值 double.infinity 方式。

      Row(
        children: <Widget>[
          Expanded(
            child: Container(
              height: 50,
              child: RaisedButton(
                child: Text('组合控制自适应'),
                onPressed: () {},
              ),
            ),
          )
        ],
      ),
    
      SizedBox(height: 30),
    
      Container(
        width: double.infinity,
        height: 40,
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          child: Text('无穷宽值方式'),
          onPressed: () {},
        ),
      )
    

    效果如下:

    RaisedButton3.gif
    4、圆角 & 圆形 按钮

    RasedButton 圆角可以通过 shape 属性控制,shape 属性支持传入 RoundedRectangleBorder 并且指定 RoundedRectangleBorder.borderRadius 的圆角值实现按钮圆角。

      RaisedButton(
        child: Text('圆角按钮',style: TextStyle(color: Colors.white)),
        color: Colors.green,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(25),
        ),
        onPressed: () {},
      ),
    

    效果如下:

    RaisedButton4.png

    RasedButton 圆形可以借助 RaisedButton.shape 来实现,本身 shape 支持传入的属性是 ShapeBorder 即可,而 CircleBorder 也是继承自 ShapeBorder。需要注意的是通过这种方式实现圆形按钮,当内部文字过长就会显示不出来,需要外部容器包装下。

      SizedBox(
        height: 70,
        child:   RaisedButton(
          child: Text('圆形按钮',style: TextStyle(color: Colors.white)),
          color: Colors.green,
          shape: CircleBorder(
            side: BorderSide(color: Colors.blue),
          ),
          onPressed: () {},
        ),
      ),
    

    效果如下:

    RaisedButton5.png
    5、图标按钮

    造函数 RaisedButton.icon 中可以配置一个带有图标的按钮。

      factory RaisedButton.icon({
        Key key,
        @required VoidCallback onPressed,
        ValueChanged<bool> onHighlightChanged,
        ButtonTextTheme textTheme,
        Color textColor,
        Color disabledTextColor,
        Color color,
        Color disabledColor,
        Color focusColor,
        Color hoverColor,
        Color highlightColor,
        Color splashColor,
        Brightness colorBrightness,
        double elevation,
        double highlightElevation,
        double disabledElevation,
        ShapeBorder shape,
        Clip clipBehavior,
        FocusNode focusNode,
        MaterialTapTargetSize materialTapTargetSize,
        Duration animationDuration,
        @required Widget icon,
        @required Widget label,
      }) = _RaisedButtonWithIcon;
    

    运用下这种方式:

      RaisedButton.icon(
        color: Colors.pink,
        textColor: Colors.white,
        icon: Icon(Icons.settings),
        label: Text('图标按钮'),
        onPressed: () {},
      ),
    

    效果如下:

    RaisedButton6.gif

    开发中这种带有图标的按钮还是非常常见的,不过很遗憾的事 Flutter 就只给我们提供了图标放在左边的这种方式,那如果我想实现像Android 原生 TextView那样 左,上,右,下都可以定制一个图标那该怎么办呢?

    首先我们去看下Flutter中是怎么实现放置一个 Icon 的,跟进 RaisedButton.icon 源码:

        /// The type of of RaisedButtons created with [RaisedButton.icon].
        ///
        /// This class only exists to give RaisedButtons created with [RaisedButton.icon]
        /// a distinct class for the sake of [ButtonTheme]. It can not be instantiated.
        class _RaisedButtonWithIcon extends RaisedButton with MaterialButtonWithIconMixin {
          _RaisedButtonWithIcon({
            Key key,
            @required VoidCallback onPressed,
            ValueChanged<bool> onHighlightChanged,
            ButtonTextTheme textTheme,
             .....
             .....
             .....
            @required Widget icon,
            @required Widget label,
          }) : assert(elevation == null || elevation >= 0.0),
               assert(highlightElevation == null || highlightElevation >= 0.0),
               assert(disabledElevation == null || disabledElevation >= 0.0),
               assert(icon != null),
               assert(label != null),
               super(
                 key: key,
                 onPressed: onPressed,
                 .....
                 .....
                 .....
                 focusNode: focusNode,
                 materialTapTargetSize: materialTapTargetSize,
                 animationDuration: animationDuration,
                 child: Row(   // 标记1
                   mainAxisSize: MainAxisSize.min,
                   children: <Widget>[
                     icon,
                     const SizedBox(width: 8.0),
                     label,
                   ],
                 ),
               );
    

    删掉些无用相关代码,(标记1)发现其实很简单,就是定义了个 icon,然后,把这个 icon和 label用 Row 给包起来了,按照他这种方式,我们也可以去实现其他方位的图标添加了,比如我想实现顶部一个图标的我就用 Column组件去包装一个 Icon 和 一个Text 方式 ,如果想实现右边有个Icon的,我也用Row组件去包装,不过我先放Text 组件 然后在放 Icon组件。

    不过每次都要这样去写是不是很麻烦啊,能像原生一样简单点吗? 没办法自己撸一个吧,我们先自定义一个类似于Android中支持 android:drawableLeft , android:drawableTop , android:drawableRight , android:drawableBottom ,的多功能按钮 如下:

      import 'package:flutter/material.dart';
      
      class FunIconButton extends MaterialButton with MaterialButtonWithIconMixin {
        FunIconButton({
          Key key,
          @required VoidCallback onPressed,
          ValueChanged<bool> onHighlightChanged,
          ButtonTextTheme textTheme,
          Color textColor,
          Color disabledTextColor,
          Color color,
          Color disabledColor,
          Color focusColor,
          Color hoverColor,
          Color highlightColor,
          Color splashColor,
          Brightness colorBrightness,
          double elevation,
          double highlightElevation,
          double disabledElevation,
          ShapeBorder shape,
          Clip clipBehavior = Clip.none,
          FocusNode focusNode,
          MaterialTapTargetSize materialTapTargetSize,
          Duration animationDuration,
          double minWidth,
          double height,
          Widget leftIcon,
          Widget topIcon,
          Widget rightIcon,
          Widget bottomIcon,
          EdgeInsetsGeometry textPadding,
          Widget label,
        })  : assert(elevation == null || elevation >= 0.0),
              assert(highlightElevation == null || highlightElevation >= 0.0),
              assert(disabledElevation == null || disabledElevation >= 0.0),
              super(
              key: key,
              onPressed: onPressed,
              onHighlightChanged: onHighlightChanged,
              textTheme: textTheme,
              textColor: textColor,
              disabledTextColor: disabledTextColor,
              color: color,
              disabledColor: disabledColor,
              focusColor: focusColor,
              hoverColor: hoverColor,
              highlightColor: highlightColor,
              splashColor: splashColor,
              colorBrightness: colorBrightness,
              elevation: elevation,
              highlightElevation: highlightElevation,
              disabledElevation: disabledElevation,
              shape: shape,
              clipBehavior: clipBehavior,
              focusNode: focusNode,
              materialTapTargetSize: materialTapTargetSize,
              animationDuration: animationDuration,
              minWidth: minWidth,
              height: height,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Offstage(
                    offstage: topIcon == null,
                    child: topIcon,
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Offstage(
                        offstage: leftIcon == null,
                        child: leftIcon,
                      ),
                      Padding(
                        padding: textPadding,
                        child: label,
                      ),
                      Offstage(
                        offstage: rightIcon == null,
                        child: rightIcon,
                      ),
                    ],
                  ),
                  Offstage(
                    offstage: bottomIcon == null,
                    child: bottomIcon,
                  ),
                ],
              ),
            );
      }
    

    除了支持 Flutter Button中常用的属性外,我们还添了如下属性:

        属性名       类型              作用
    
        leftIcon     Widget           左边添加一个图标,可以是其他 Widget 组件
        
        topIcon      Widget           顶部添加一个图标,同理
        
        rightIcon    Widget           右边添加一个图标,同理
        
        bottomIcon   Widget           底部添加一个图标,同理
    

    leftIcon接收的是一个 Widget 能很好拓展你放其他的组件进去,不一定就是一个图标,为了更加灵活。下面来运用试试。

      FunIconButton(
        label:Text('多功能按钮',style: TextStyle(color: Colors.deepPurple)),
        color: Colors.blue,
        textColor: Colors.white,
        onPressed: () {},
        minWidth: 240,
        leftIcon: Image.asset(
          "images/mm.jpg",
          width: 24,
          height: 24,
        ),
        rightIcon: Icon(Icons.group),
        topIcon: Icon(Icons.save),
        bottomIcon: Icon(Icons.score),
        textPadding: EdgeInsets.only(left: 10, right: 10),
    
      ),
    

    效果如下:

    自定义RaisedButton7.gif

    二、FlatButton

    FlatButton 没有 RaisedButton 默认的阴影,因此看起来是扁平化的,没有凸出感觉。

         FlatButton(
            //按钮文字颜色
            textColor: Colors.white,
            //按钮禁用时的背景颜色
            disabledColor:Colors.grey,
            //按钮禁用时的文字颜色
            disabledTextColor: Colors.grey,
            //正常状态下的背景颜色
            color: Colors.blue,
            //按钮按下时的背景颜色
            highlightColor: Colors.blue[700],
            //按钮主题,默认是浅色主题
            colorBrightness: Brightness.dark,
            //外形
            splashColor: Colors.grey,
            // button 显示的文字
            child: Text("纳尼"),
            //圆角边框
            shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
            //按钮点击回调
            onPressed: () => {},
          )
    
    FlatButton.png

    三、OutlineButton 边框按钮

    OutlineButton 允许我们给 Button 指定 边框和样式,开发中这种 Button 非常常见,运用下:

      OutlineButton(
        child: Text('边框按钮'),
        onPressed: () {},
      ),
      OutlineButton(
        borderSide: BorderSide(color: Colors.pink),
        child: Text('边框按钮'),
        onPressed: () {},
      ),
    

    效果如下:

    OutlineButton.gif

    四、IconButton 图标按钮

    此 Button 已经在案例中使用太多次了,常用且简单。 IconButton 默认实现了高度和宽度的设置,并且是一个圆形的 Button,因此在使用 IconButton 的时候我们可以通过 Icon.size 控制图标大小,也能够控制 padding 属性。

      //IconButton
      IconButton(
        splashColor: Colors.pink,
        color: Colors.pink,
        icon: Icon(Icons.send,size: 50,),
        onPressed: () {},
      ),
      IconButton(
        splashColor: Colors.pink,
        color: Colors.pink,
        padding: EdgeInsets.all(0),
        icon: Icon(Icons.settings),
        onPressed: () {},
      )
    

    效果如下:

    IconButton.gif

    五、ButtonBar 按钮组

    ButtonBar 可以默认实现一个按钮组,通过 children 属性可以传入多个 Button,说白了 ButtonBar 就是一个容器,可以统一管理子元素的位置信息。

    构造函数:

       const ButtonBar({
        Key key,
        this.alignment = MainAxisAlignment.end,
        this.mainAxisSize = MainAxisSize.max,
        this.children = const <Widget>[],
      }) : super(key: key);
    

    实践运用:

        ButtonBar(
          alignment:MainAxisAlignment.center ,
          children: <Widget>[
            RaisedButton(
              color: Colors.pink,
              textColor: Colors.white,
              child: Text('按钮组'),
              onPressed: () {},
            ),
            FlatButton(
              color: Colors.pink,
              textColor: Colors.white,
              child: Text('按钮组'),
              onPressed: () {},
            )
          ],
        )
    

    效果如下:

    ButtonBar.png

    六、FloatingActionButton 悬浮按钮

    FloatingActionButton 可以实现浮动按钮,使用场景也是非常多 如:各种购物商场的 返回顶部按钮。

    常用属性:
        属性名称                属性值
    
        child                   子视图,一般为 Icon
    
        tooltip                 FAB 被长按时显示,也是无障碍功能
    
        backgroundColor         背景颜色
        
        foregroundColor         前景色
    
        elevation               未点击的时候的阴影
    
        hignlightElevation      点击时阴影值,默认 12.0
    
        onPressed               点击事件回调
    
        shape                   可以定义 FAB 的形状等
    
        mini                    是否是 mini 类型默认 false
        
        heroTag                 hero效果使用的tag,系统默认会给所有FAB使用同一个tag,方便做动画效果
        
        isExtended              是否为”extended”类型
    

    简单运用:

        import 'package:flutter/foundation.dart';
        import 'package:flutter/material.dart';
    
        class HomePage extends StatefulWidget {
          HomePage({Key key}) : super(key: key);
    
          HomePageState createState() => HomePageState();
        }
    
        class HomePageState extends State<HomePage> {
          void handlerDrawerButton() {
    
          }
          @override
          Widget build(BuildContext context) {
    
            return Scaffold(
    
              //FloatingActionButton
              floatingActionButton: FloatingActionButton(
                elevation: 0,
                backgroundColor: Colors.green,
                foregroundColor: Colors.purpleAccent,
                child: Icon(
                  Icons.build,
                  size: 30,
                  color: Colors.white,
                ),
                onPressed: () {},
              ),
              floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
    
              backgroundColor: Colors.blue,
              
              body: Container(
                child: Center(
                  child: Text("主页"),
                ),
              ),
            );
          }
        }
    

    效果如下绿色悬浮按钮:

    FAB.png
    FloatingActionButton 的不同类型

    FAB 分为三种类型:常规, mini, 和 extended。下面来看这三种有什么区别:

    FAB对比.png

    可以看出 设置mini 时,FAB按钮变小了。使用FloatingActionButton.extended 构造函数可以实现图文并茂的悬浮按钮。

    FloatingActionButton 的位置选择

    Scaffold Widget中有一个 floatingActionButtonLocation属性 结合FAB使用,可以指定悬浮按钮的摆放位置。

    FAB_localtion.png

    目前提供了 7 种位置可以选择,在使用时可以分别试试不同的位置效果吧。

    七、模仿闲鱼底部导航效果:

    为什么要模仿闲鱼? 因为他牛逼啊,哈哈。毕竟别人是国内 Flutter 最大的团队!!!

    闲鱼的底部菜单按钮是这样子的:

    闲鱼.png

    结合上面学到的按钮组件 FloatingActionButton 其实我们可以很轻松实现闲鱼效果。我们的案例中已经有创建好的底部菜单,那就充分利用起来吧,进入我们之前写 Tabs.dart 中,在 Scaffold 配置 floatingActionButton 属性,之前没有跟着我写的同学,可以在文末去翻阅源码。

         floatingActionButton:Container(
                height: 80,
                width: 80,
                //实现一个圆形
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(40),
                  color: Colors.white,
                ),
                //距离上边 10个单位
                margin: EdgeInsets.only(top:10),
                // 8个单位的内边距,让周边有浮出感
                padding: EdgeInsets.all(8),
                child: FloatingActionButton(
                  child: Icon(Icons.add),
                  backgroundColor: this._currentIndex==1?Colors.red:Colors.deepPurple,
                  onPressed: (){
                    setState(() {
                      this._currentIndex=1;
                    });
                  },
                ),
              ),
              //指定显示位置
              floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    

    最终效果如下:

    实战闲鱼.gif

    非常轻松的就实现了,没什么难度。O(∩_∩)O哈哈~

    下面贴出本章中的全部实例图,看图回忆下本章知识点吧!

    按钮实例图.png

    好了本章节到此结束,又到了说再见的时候了,如果你喜欢请留下你的小红星,你们的支持才是创作的动力,如有错误,请热心的你留言指正, 谢谢大家观看,下章再会 O(∩_∩)O

    实例源码地址: https://github.com/zhengzaihong/flutter_learn

    相关文章

      网友评论

          本文标题:Flutter第八章(RaisedButton ,FlatBut

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