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 shapeelevation的动画更改的持续时间。

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,
                    )))),