Flutter Button使用

Material 组件库中有多种按钮组件如ElevatedButton、TextButton、OutlineButton等,它们的父类是于ButtonStyleButton。

基本的按钮特点:

1.按下时都会有"水波文动画"。

2.onPressed属性设置点击回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。

ElevatedButton

简单实现

Dart 复制代码
  const ElevatedButton({
    super.key,
    required super.onPressed,
    super.onLongPress,
    super.onHover,
    super.onFocusChange,
    super.style,
    super.focusNode,
    super.autofocus = false,
    super.clipBehavior,
    super.statesController,
    required super.child,
    super.iconAlignment,
  });
Dart 复制代码
import 'package:flutter/material.dart';

class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            ElevatedButton(
              onPressed: () {
                print('ElevatedButton clicked');
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(150, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
}

对上面的属性做简单介绍:

  • child: Text("Click ElevatedButton")设置按钮显示的文本为"Click ElevatedButton"。
  • onPressed:设置按钮点击事件。
  • style:使用ElevatedButton.styleFrom方法设置按钮的样式,包括背景色、文本颜色、阴影效果、最小宽度和形状等。

Dart 复制代码
2024-09-07 15:44:54.993 12985-13050 flutter       I  ElevatedButton clicked
2024-09-07 15:44:56.418 12985-13050 flutter       I  ElevatedButton clicked
2024-09-07 15:44:57.601 12985-13050 flutter       I  ElevatedButton clicked
2024-09-07 15:44:58.044 12985-13050 flutter       I  ElevatedButton clicked
2024-09-07 15:47:37.981 12985-13050 flutter       I  ElevatedButton clicked
Dart 复制代码
  static ButtonStyle styleFrom({
    Color? foregroundColor,
    Color? backgroundColor,
    Color? disabledForegroundColor,
    Color? disabledBackgroundColor,
    Color? shadowColor,
    Color? surfaceTintColor,
    Color? iconColor,
    Color? disabledIconColor,
    Color? overlayColor,
    double? elevation,
    TextStyle? textStyle,
    EdgeInsetsGeometry? padding,
    Size? minimumSize,
    Size? fixedSize,
    Size? maximumSize,
    BorderSide? side,
    OutlinedBorder? shape,
    MouseCursor? enabledMouseCursor,
    MouseCursor? disabledMouseCursor,
    VisualDensity? visualDensity,
    MaterialTapTargetSize? tapTargetSize,
    Duration? animationDuration,
    bool? enableFeedback,
    AlignmentGeometry? alignment,
    InteractiveInkFeatureFactory? splashFactory,
    ButtonLayerBuilder? backgroundBuilder,
    ButtonLayerBuilder? foregroundBuilder,
  }) 

去除去掉ElevatedButton边距

Dart 复制代码
import 'package:flutter/material.dart';

class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            ElevatedButton(
                onPressed: () {
                  print('ElevatedButton clicked');
                },
                child: Text("Click ElevatedButton"),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size.zero,
                  padding: EdgeInsets.zero,
                  tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                ))
          ],
        ),
      ),
    );
  }
}

水平填充满

Dart 复制代码
import 'package:flutter/material.dart';

class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            ElevatedButton(
              onPressed: () {
                print('ElevatedButton clicked');
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
}

TextButton

Dart 复制代码
  const TextButton({
    super.key,
    required super.onPressed,
    super.onLongPress,
    super.onHover,
    super.onFocusChange,
    super.style,
    super.focusNode,
    super.autofocus = false,
    super.clipBehavior,
    super.statesController,
    super.isSemanticButton,
    required Widget super.child,
    super.iconAlignment,
  });

简单实现

Dart 复制代码
import 'package:flutter/material.dart';

class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            TextButton(
                onPressed: () {
                  print('TextButton clicked');
                },
                autofocus: false,
                style: ButtonStyle(
                    textStyle: WidgetStateProperty.all(
                        TextStyle(fontSize: 20, color: Colors.red))),
                child: Text("Click TextButton"))
          ],
        ),
      ),
    );
  }
}

注意:上面通过 textStyle: WidgetStateProperty.all(TextStyle(fontSize: 20, color: Colors.red))来设置按钮字体颜色是无效的,发现颜色还是蓝色,而不是红色。

通过foregroundColor:WidgetStateProperty.all(Colors.yellow))才会生效。

Dart 复制代码
import 'package:flutter/material.dart';


class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            TextButton(
                onPressed: () {
                  print('TextButton clicked');
                },
                autofocus: false,
                style: ButtonStyle(
                    textStyle: WidgetStateProperty.all(
                        TextStyle(fontSize: 20, color: Colors.red)),
                    foregroundColor:
                        WidgetStateProperty.all(Colors.yellow)),
                child: Text("Click TextButton"))
          ],
        ),
      ),
    );
  }
}

设置按钮按下时,获取焦点时、默认状态时的颜色

Dart 复制代码
import 'package:flutter/material.dart';


class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            TextButton(
                onPressed: () {
                  print('TextButton clicked');
                },
                autofocus: false,
                style: ButtonStyle(
                  textStyle: WidgetStateProperty.all(
                      const TextStyle(fontSize: 20, color: Colors.red)),
                  foregroundColor: WidgetStateProperty.resolveWith(
                    (states) {
                      if (states.contains(MaterialState.focused) &&
                          !states.contains(MaterialState.pressed)) {
                     //获取焦点时的颜色
                        return Colors.blue;
                      } else if (states.contains(MaterialState.pressed)) {
                         //按下时的颜色
                        return Colors.yellow;
                      }
                    //默认状态使用灰色
                      return Colors.black;
                    },
                  ),
                ),
                // foregroundColor:
                //     WidgetStateProperty.all(Colors.yellow)),
                child: Text("Click TextButton"))
          ],
        ),
      ),
    );

设置背景颜色 backgroundColor

Dart 复制代码
import 'package:flutter/material.dart';


class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            TextButton(
                onPressed: () {
                  print('TextButton clicked');
                },
                autofocus: false,
                style: ButtonStyle(
                  textStyle: WidgetStateProperty.all(
                      const TextStyle(fontSize: 20, color: Colors.red)),
                  foregroundColor: WidgetStateProperty.resolveWith(
                    (states) {
                      if (states.contains(MaterialState.focused) &&
                          !states.contains(MaterialState.pressed)) {
                      
                        return Colors.blue;
                      } else if (states.contains(MaterialState.pressed)) {
                     
                        return Colors.yellow;
                      }
                     
                      return Colors.black;
                    },
                  ),
                  backgroundColor: WidgetStateProperty.resolveWith((states) {
                
                    if (states.contains(WidgetState.pressed)) {
                      return Colors.red;
                    }
                    
                    return null;
                  }),
                ),
                // foregroundColor:
                //     WidgetStateProperty.all(Colors.yellow)),
                child: Text("Click TextButton"))
          ],
        ),
      )

其他设置

overlayColor: 设置水波纹颜色。

padding: 设置按钮内边距。

minimumSize: 设置按钮的大小。

side: 设置边框。

shape: 外边框装饰 会覆盖 side 配置的样式

Dart 复制代码
class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            TextButton(
                onPressed: () {
                  print('TextButton clicked');
                },
                autofocus: false,
                style: ButtonStyle(
                  textStyle: WidgetStateProperty.all(
                      const TextStyle(fontSize: 20, color: Colors.red)),
                  foregroundColor: WidgetStateProperty.resolveWith(
                        (states) {
                      if (states.contains(MaterialState.focused) &&
                          !states.contains(MaterialState.pressed)) {
                        return Colors.blue;
                      } else if (states.contains(MaterialState.pressed)) {
                        return Colors.yellow;
                      }

                      return Colors.black;
                    },
                  ),
                  backgroundColor: WidgetStateProperty.resolveWith((states) {
                    if (states.contains(WidgetState.pressed)) {
                      return Colors.red;
                    }

                    return null;
                  }),


                  overlayColor: WidgetStateProperty.all(Colors.red),

                  padding: WidgetStateProperty.all(EdgeInsets.all(10)),

                  minimumSize: WidgetStateProperty.all(Size(300, 100)),

                  side: WidgetStateProperty.all(
                      BorderSide(color: Colors.blue, width: 1)),

                  shape: WidgetStateProperty.all(StadiumBorder()),
                ),
                // foregroundColor:
                //     WidgetStateProperty.all(Colors.yellow)),
                child: Text("Click TextButton"))
          ],
        ),
      ),
    );
  }
}

OutlinedButton

Dart 复制代码
  const OutlinedButton({
    super.key,
    required super.onPressed,
    super.onLongPress,
    super.onHover,
    super.onFocusChange,
    super.style,
    super.focusNode,
    super.autofocus = false,
    super.clipBehavior,
    super.statesController,
    required super.child,
    super.iconAlignment,
  });

简单实现

Dart 复制代码
class ButtonWidgetPage extends StatelessWidget {
  const ButtonWidgetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Button Demo"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("TEST Button"),
            OutlinedButton(
                onPressed: () {
                  print('OutlinedButton clicked');
                },
                child: Text('Click OutlinedButton'))
          ],
        ),
      ),
    );
  }
}

Dart 复制代码
2024-09-08 11:03:01.333  4839-4871  flutter             I  OutlinedButton clicked
2024-09-08 11:03:02.027  4839-4871  flutter             I  OutlinedButton clicked
2024-09-08 11:03:02.352  4839-4871  flutter             I  OutlinedButton clicked
2024-09-08 11:03:02.547  4839-4871  flutter             I  OutlinedButton clicked
2024-09-08 11:03:02.709  4839-4871  flutter             I  OutlinedButton clicked
2024-09-08 11:03:40.339  4839-4871  flutter             I  OutlinedButton clicked

长按事件

Dart 复制代码
                onLongPress: () {
                  print('OutlinedButton onLongPress');
                },

相关属性

textStyle 字体样式

backgroundColor 背景色

foregroundColor 字体颜色

overlayColor 高亮色,按钮处于focused, hovered, pressed时的颜色

shadowColor 阴影颜色

elevation 阴影值

padding padding

minimumSize 最小尺寸

side 边框

shape 形状

mouseCursor 鼠标指针的光标进入或者悬停在此按钮上

visualDensity 按钮布局的紧凑程度

tapTargetSize 响应触摸的区域

animationDuration [shape]和[elevation]的动画更改的持续时间。

enableFeedback 检测到的手势是否应提供声音和/或触觉反馈。

设置字体大小(注意:这里设置颜色不会生效)

Dart 复制代码
  style: ButtonStyle(
                  textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30))
                ),

backgroundColor 背景色

Dart 复制代码
style: ButtonStyle(
  textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
  backgroundColor: WidgetStateProperty.all(Colors.red),
)

foregroundColor 字体颜色

Dart 复制代码
             style: ButtonStyle(
                  textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
                  backgroundColor: WidgetStateProperty.all(Colors.red),
                  foregroundColor: WidgetStateProperty.all(Colors.yellow),
                ),

overlayColor 高亮色,按钮处于focused, hovered, pressed时的颜色

Dart 复制代码
style: ButtonStyle(
  textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
  backgroundColor: WidgetStateProperty.all(Colors.red),
  foregroundColor: WidgetStateProperty.all(Colors.yellow),
  overlayColor: WidgetStateProperty.all(Colors.blue),
)

side 边框

Dart 复制代码
         style: ButtonStyle(
                  textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
                  backgroundColor: WidgetStateProperty.all(Colors.red),
                  foregroundColor: WidgetStateProperty.all(Colors.yellow),
                  overlayColor: WidgetStateProperty.all(Colors.blue),
                  side: WidgetStateProperty.all(BorderSide(width: 1,color: Colors.green)),
                )

shadowColor 阴影颜色 & elevation 阴影值

Dart 复制代码
style: ButtonStyle(
  textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
  backgroundColor: WidgetStateProperty.all(Colors.red),
  foregroundColor: WidgetStateProperty.all(Colors.yellow),
  overlayColor: WidgetStateProperty.all(Colors.blue),
  side: WidgetStateProperty.all(
	  BorderSide(width: 1, color: Colors.green)),
  shadowColor: WidgetStateProperty.all(Colors.black),
  elevation: WidgetStateProperty.all(10),
)

shape 形状

棱形

Dart 复制代码
style: ButtonStyle(
  textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
  backgroundColor: WidgetStateProperty.all(Colors.red),
  foregroundColor: WidgetStateProperty.all(Colors.yellow),
  overlayColor: WidgetStateProperty.all(Colors.blue),
  side: WidgetStateProperty.all(
	  BorderSide(width: 1, color: Colors.green)),
  shadowColor: WidgetStateProperty.all(Colors.black),
  elevation: WidgetStateProperty.all(10),
  shape: WidgetStateProperty.all(BeveledRectangleBorder(borderRadius: BorderRadius.circular(10))),
)

圆角弧度

Dart 复制代码
 style: ButtonStyle(
                    textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
                    backgroundColor: WidgetStateProperty.all(Colors.red),
                    foregroundColor: WidgetStateProperty.all(Colors.yellow),
                    overlayColor: WidgetStateProperty.all(Colors.blue),
                    side: WidgetStateProperty.all(
                        BorderSide(width: 1, color: Colors.green)),
                    shadowColor: WidgetStateProperty.all(Colors.black),
                    elevation: WidgetStateProperty.all(10),
                    //shape: WidgetStateProperty.all(BeveledRectangleBorder(borderRadius: BorderRadius.circular(10))),
                    shape: WidgetStateProperty.all(StadiumBorder(
                        side: BorderSide(
                      style: BorderStyle.solid,
                      color: Colors.blue,
                    )))),