美文网首页
Flutter 组件之 按钮、Wrap、StatefulWidg

Flutter 组件之 按钮、Wrap、StatefulWidg

作者: Abner_XuanYuan | 来源:发表于2023-10-12 00:03 被阅读0次

    1、按钮

    1、属性
    onPressed:必填参数,按下按钮时触发的回调,接收一个方法,传 null 表示按钮禁用,会显示禁用相关样式。
    child:子组件。
    style:ButtonStyle 类型的样式。
    

    ButtonStyle 属性

    ButtonStyle ButtonStyle({
      MaterialStateProperty<TextStyle?>? textStyle,  //文本样式
      MaterialStateProperty<Color?>? backgroundColor,  //背景色
      MaterialStateProperty<Color?>? foregroundColor,  //前景色(文本颜色)
      MaterialStateProperty<Color?>? overlayColor,  //高亮色,按钮按下之后的颜色
      MaterialStateProperty<Color?>? shadowColor,  //阴影色
      MaterialStateProperty<Color?>? surfaceTintColor,  //表面色调颜色
      MaterialStateProperty<double?>? elevation,  //阴影度
      MaterialStateProperty<EdgeInsetsGeometry?>? padding,  //内容边距
      MaterialStateProperty<Size?>? minimumSize,  //最小尺寸
      MaterialStateProperty<Size?>? fixedSize,  //按钮尺寸
      MaterialStateProperty<Size?>? maximumSize,  //最大尺寸
      MaterialStateProperty<Color?>? iconColor,  //图标颜色
      MaterialStateProperty<double?>? iconSize,  //图标大小
      MaterialStateProperty<BorderSide?>? side,  //设置边框
      MaterialStateProperty<OutlinedBorder?>? shape,  //设置按钮的形状
      MaterialStateProperty<MouseCursor?>? mouseCursor,  //桌面端鼠标样式
      VisualDensity? visualDensity,  //视觉密度
      MaterialTapTargetSize? tapTargetSize,  //响应触摸区域
      Duration? animationDuration,  //动画持续时间
      bool? enableFeedback,  //是否启用反馈,如长按震动
      AlignmentGeometry? alignment,  //子组件对齐样式
      InteractiveInkFeatureFactory? splashFactory,  //没有水波纹效果
    })
    
    2、按钮分类

    ElevatedButton:即"凸起"按钮,它默认带有阴影和灰色背景。按下后,阴影会变大。

    ElevatedButton ElevatedButton({
      Key? key,
      required void Function()? onPressed,  //点击事件
      void Function()? onLongPress,  //长按事件
      void Function(bool)? onHover,  //鼠标悬停时回调
      void Function(bool)? onFocusChange,  //焦点
      ButtonStyle? style,
      FocusNode? focusNode,  //用于焦点管理和监听
      //如果当前未将其范围内的其他节点作为焦点,则将此小部件选择为初始焦点时为 True
      bool autofocus = false,
      Clip clipBehavior = Clip.none,  //裁剪
      MaterialStatesController? statesController,
      required Widget? child,
    })
    

    示例

    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return ElevatedButton(
          onPressed: () {
            print("ElevatedButton -- Click");
          },
          onLongPress: () {
            print("ElevatedButton -- LongClick");
          },
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all(Colors.green),
            foregroundColor: MaterialStateProperty.all(Colors.white),
            shadowColor: const MaterialStatePropertyAll(Colors.greenAccent),
            overlayColor: const MaterialStatePropertyAll(Colors.transparent),//按钮点击时的高亮色
          ),
          child: const Text("ElevatedButton"),
        );
      }
    }
    

    TextButton:文本按钮,默认背景透明并不带阴影。按下后,会有背景色。

    //TextButton
    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return TextButton(
          child: const Text("TextButton"),
          onPressed: () {
            print("TextButton -- Click");
          },
          onLongPress: () {
            print("TextButton -- Long Click");
          },
          autofocus: true,
          style: TextButton.styleFrom(
            backgroundColor: Colors.grey,
            foregroundColor: Colors.red,
            shadowColor: Colors.green,
          ),
        );
      }
    }
    

    OutlinedButton:默认有一个边框,不带阴影且背景透明。按下后,边框颜色会变亮、同时出现背景和阴影。

    //OutlinedButton
    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return OutlinedButton(
          onPressed: () {
            print("OutlinedButton -- Click");
          },
          onLongPress: () {
            print("OutlinedButton -- Long Click");
          },
          style: const ButtonStyle(
            backgroundColor: MaterialStatePropertyAll(Colors.green),
            foregroundColor: MaterialStatePropertyAll(Colors.black),
            overlayColor: MaterialStatePropertyAll(Colors.transparent),
          ),
          child: const Text("OutlinedButton"),
        );
      }
    }
    

    IconButton:是一个可点击的 Icon,不包括文字,默认没有背景,点击后会出现背景。

    //IconButton
    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return IconButton(
          icon: const Icon(Icons.thumb_up),
          onPressed: () {
            print("IconButton -- Click");
          },
          iconSize: 40, //图标大小
          padding: const EdgeInsets.all(30),
          alignment: Alignment.topLeft,
    
          //以下两行可以取消按钮的默认点击效果
          splashColor: Colors.transparent,
          highlightColor: Colors.transparent,
        );
      }
    }
    

    浮动按钮:是一个圆形图标按钮,它触发应用程序中的主要操作。
    FloatingActionButton:它创建一个简单的圆形浮动按钮,其中包含一个子部件。T 必须有一个子参数来显示 widget 。

    //FloatingActionButton
    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return FloatingActionButton(onPressed: () { 
          print("FloatingActionButton -- Click");
         },
         backgroundColor: Colors.green,
         foregroundColor: Colors.white,
         child: const Icon(Icons.add),
         );
      }
    }
    

    FloatingActionButton.extended:它创建了一个宽的浮动按钮,其中包含一个图标和一个标签。它使用标签和图标参数,而不是子参数。

    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return FloatingActionButton.extended(
            onPressed: () {
              print("FloatingActionButton.extended -- Click");
            },
            icon: const Icon(Icons.add),
            backgroundColor: Colors.green,
            foregroundColor: Colors.black,
            label: const Text("Add"));
      }
    }
    

    自适应按钮

    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
              child: Container(
                height: 60,
                margin: const EdgeInsets.all(10),
                child: ElevatedButton(
                  child: const Text('自适应按钮'),
                  onPressed: () {
                    print("自适应按钮");
                  },
                ),
              ),
            )
          ],
        );
      }
    }
    

    修改按钮宽高

    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          width: double.infinity,
          height: 50,
          child: ElevatedButton(
              onPressed: () {
                print("自定义宽高");
              },
              style: ElevatedButton.styleFrom(
                foregroundColor: Colors.red,
                backgroundColor: Colors.green,
              ),
              child: const Text("自定义宽高")),
        );
      }
    }
    

    2、Wrap

    Wrap 可以实现流布局,单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 则跟 Column 表现几乎一致。但 Row 与 Column 都是单行单列的,Wrap 则不是,mainAxis 上空间不足时,则向 crossAxis 上去扩展显示。

    1、属性
    Wrap Wrap({
      Key? key,
      Axis direction = Axis.horizontal,    //主轴的方向,默认水平
      WrapAlignment alignment = WrapAlignment.start,    //主轴的对其方式
      double spacing = 0.0,    //主轴方向上的间距
     //run 的对齐方式。run 可以理解为新的行或者列,如果是水平方向布局的话,run 可以理解为新的一行。
      WrapAlignment runAlignment = WrapAlignment.start,   
      double runSpacing = 0.0,  //run的间距
      WrapCrossAlignment crossAxisAlignment = WrapCrossAlignment.start,    //次轴对齐方式
      TextDirection? textDirection,    //文本方向
      VerticalDirection verticalDirection = VerticalDirection.down,    // children 摆放顺序,默认是down。
      Clip clipBehavior = Clip.none,
      List<Widget> children = const <Widget>[],
    })
    
    2、使用
    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      List<Widget> _customButton() {
        List<Widget> list = [];
        for (var e in listData) {
          list.add(XSHButton(e["title"], onPressed: () {
            print("标题: " + e["title"]);
          }));
        }
        return list;
      }
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.all(3),
          child: Wrap(
            spacing: 5,
            runSpacing: 5,
            // direction: Axis.vertical,
            // alignment: WrapAlignment.start,
            // runAlignment: WrapAlignment.center,
            children: _customButton(),
          ),
        );
      }
    }
    
    //自定义按钮
    // ignore: must_be_immutable
    class XSHButton extends StatelessWidget {
      String text;
      void Function() onPressed;
    
      XSHButton(this.text, {super.key, required this.onPressed});
    
      @override
      Widget build(BuildContext context) {
        return ElevatedButton(
          style: const ButtonStyle(
            backgroundColor:
                MaterialStatePropertyAll(Color.fromARGB(255, 236, 233, 233)),
            foregroundColor: MaterialStatePropertyAll(Colors.black45),
          ),
          onPressed: onPressed,
          child: Text(text),
        );
      }
    }
    

    3、在 Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget 或者 StatefulWidget。

    StatelessWidget是无状态组件,状态不可变的 widget。
    StatefulWidget是有状态组件,持有的状态可能在 widget 生命周期改变。如果想改变页面中数据的话这个时候就需要用到 StatefulWidget。

    使用示例

    //计数器
    class HomePage extends StatefulWidget {
      const HomePage({super.key});
    
      @override
      State<HomePage> createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      int countNum = 0;
      @override
      Widget build(BuildContext context) {
        return Center(
          child: Column(
            children: [
              const SizedBox(
                height: 100,
              ),
              Text(
                "数字是: $countNum",
                style: const TextStyle(color: Colors.red, fontSize: 20),
              ),
              const SizedBox(
                height: 100,
              ),
              ElevatedButton(
                  onPressed: () {
                    setState(() {
                      countNum++;
                    });
                  },
                  child: const Text("增加")),
            ],
          ),
        );
      }
    }
    
    //动态列表
    class HomePage1 extends StatefulWidget {
      const HomePage1({super.key});
    
      @override
      State<HomePage1> createState() => _HomePage1State();
    }
    
    class _HomePage1State extends State<HomePage1> {
    
      List<String> list = [];
      @override
      Widget build(BuildContext context) {
        return ListView(
          children: [
            Column(
              children: list.map((e) {
                return ListTile(
                  title: Text(e),
                );
              }).toList(),
            ),
            const SizedBox(
              height: 10,
            ),
            Padding(
              padding: const EdgeInsets.all(10),
              child: ElevatedButton(
                  onPressed: () {
                    setState(() {
                      list.add("第 ${list.length + 1} 条数据");
                    });
                  },
                  child: const Text("增加一条数据")),
            ),
          ],
        );
      }
    }
    

    刷新页面:setState 方法。

    相关文章

      网友评论

          本文标题:Flutter 组件之 按钮、Wrap、StatefulWidg

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