Flutter 中的 ButtonStyle 和 MaterialStateProperty:深入了解

这篇具有很好参考价值的文章主要介绍了Flutter 中的 ButtonStyle 和 MaterialStateProperty:深入了解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Flutter 中的 ButtonStyle 和 MaterialStateProperty 是在 Flutter 2.0 发布时引入的。在 Flutter 1 中,我们可以通过设置 textColor、backgroundColor 等参数来快速配置按钮的样式。但是在 Flutter 2 中,这些参数被废弃了,取而代之的是 ButtonStyle。ButtonStyle 可以通过 MaterialStateProperty 来支持不同平台下的交互状态展示。本文将深入探讨这两个新特性。

1.MaterialStateProperty

MaterialStateProperty 的设计理念基于 Material Design 去针对全平台的交互进行兼容。在 MaterialStateProperty 体系中,有一个 MaterialState 枚举,它包含了多种不同的状态,例如 disabled、hovered、focused、selected、pressed、dragged、error 等。MaterialStateProperty 可以通过这些状态来控制控件的样式。

举个例子,假设我们需要在按钮悬停时修改按钮的背景颜色。在Flutter 1 中,我们可以这样写:

FlatButton(
  onPressed: () {},
  color: Colors.blue,
  hoverColor: Colors.green,
  child: Text('Button'),
)

但是在Flutter 2 中,我们需要使用 ButtonStyle 和 MaterialStateProperty 来实现相同的效果。代码如下:

TextButton(
  onPressed: () {},
  style: ButtonStyle(
    backgroundColor: MaterialStateProperty.resolveWith((states) {
      if (states.contains(MaterialState.hovered)) {
        return Colors.green;
      }
      return Colors.blue;
    }),
  ),
  child: Text('Button'),
)

在上述代码中,我们使用MaterialStateProperty.resolveWith 方法来处理按钮的背景颜色,这样就可以轻松地实现不同状态下的样式切换。在这个例子中,我们使用 MaterialState.hovered 来处理按钮悬停时的样式。

需要注意的是,MaterialStateProperty 不仅适用于按钮,还适用于其他控件,例如 Checkbox、Radio、Slider 等。

2.ButtonStyle

ButtonStyle 是 Flutter 中一种全新的样式定义方式,它用于定义控件的样式。ButtonStyle 的设计目的是为了在不同平台下提供一致的外观和行为。例如,当用户在不同的操作系统上运行应用程序时,ButtonStyle 可以确保按钮的样式和行为都是一致的。

ButtonStyle 由多个 MaterialStateProperty 组成,每个 MaterialStateProperty 对应一个控件状态。我们可以使用 MaterialStateProperty 来定义控件不同状态下的样式。例如,我们可以通过定义 MaterialStateProperty 来修改按钮在不同状态下的背景颜色、前景色、字体大小等。

举个例子,假设我们需要创建一个带有自定义样式的按钮。在Flutter 1 中,我们可以这样写:

FlatButton(
  onPressed: () {},
  color: Colors.blue,
  textColor: Colors.white,
  child: Text('Button'),
)

但是在Flutter 2 中,我们需要使用 ButtonStyle 和 MaterialStateProperty 来实现相同的效果。代码如下:

TextButton(
  onPressed: () {},
  style: ButtonStyle(
    backgroundColor: MaterialStateProperty.all(Colors.blue),
    foregroundColor: MaterialStateProperty.all(Colors.white),
    textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
  ),
  child: Text('Button'),
)

在上述代码中,我们使用MaterialStateProperty.all 方法来设置按钮的背景颜色、前景色和字体大小。MaterialStateProperty.all 方法可以将一个值应用到所有的状态中。

需要注意的是,ButtonStyle 的属性有很多,例如 elevation、padding、shape 等等。我们可以使用 MaterialStateProperty 来设置每个属性在不同状态下的值。例如,我们可以通过定义 MaterialStateProperty 来修改按钮在悬停状态下的阴影。

TextButton(
  onPressed: () {},
  style: ButtonStyle(
    elevation: MaterialStateProperty.resolveWith((states) {
      if (states.contains(MaterialState.hovered)) {
        return 10.0;
      }
      return 5.0;
    }),
  ),
  child: Text('Button'),
)

在上述代码中,我们使用MaterialStateProperty.resolveWith 方法来处理按钮的阴影。当按钮处于悬停状态时,我们将阴影的值设置为 10.0,否则设置为 5.0。

3.Theme

如果你希望在全局范围内应用某个样式,可以使用Flutter 中的 Theme。Theme 可以用来定义全局主题,包括文本样式、颜色、字体、按钮样式等等。在 ButtonStyle 中,我们也可以使用 Theme 来定义全局按钮样式。

举个例子,假设我们需要在全局范围内应用自定义按钮样式。我们可以这样写:

Theme(
  data: ThemeData(
    textButtonTheme: TextButtonThemeData(
      style: ButtonStyle(
        backgroundColor: MaterialStateProperty.all(Colors.blue),
        foregroundColor: MaterialStateProperty.all(Colors.white),
        textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
      ),
    ),
  ),
  child: TextButton(
    onPressed: () {},
    child: Text('Button'),
  ),
)

在上述代码中,我们使用Theme 来定义全局的按钮样式。我们将 ButtonStyle 定义在 textButtonTheme 中,并将其应用到 TextButton 中。

4.在Flutter 中,ButtonStyle 和 MaterialStateProperty 为我们提供了一种更加灵活、可定制的方式来定义控件样式。ButtonStyle 和 MaterialStateProperty 可以帮助我们实现不同状态下的样式切换,并支持不同平台下的交互状态展示。我们可以使用 ButtonStyle 和 MaterialStateProperty 来定义按钮样式、文本样式、颜色、字体、阴影等等。如果你需要在全局范围内应用某个样式,可以使用 Theme 来定义全局主题。

除了以上介绍的基本用法,ButtonStyle 还有一些高级用法,可以让我们更好地定制控件样式。下面我们将一一介绍。

5.Stateful Button

如果你需要自定义一些不同状态下的样式,可以使用 StatefulButton。StatefulButton 继承自 StatefulWidget,它包含了一个 ValueNotifier<bool>,用来表示按钮的选中状态。在按钮选中时,我们可以自定义按钮的样式。

举个例子,我们可以创建一个带有自定义选中状态的按钮:

class MyStatefulButton extends StatefulWidget {
  const MyStatefulButton({Key? key}) : super(key: key);

  @override
  _MyStatefulButtonState createState() => _MyStatefulButtonState();
}

class _MyStatefulButtonState extends State<MyStatefulButton> {
  final ValueNotifier<bool> _selected = ValueNotifier(false);

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: _selected,
      builder: (BuildContext context, bool isSelected, Widget? child) {
        return TextButton(
          onPressed: () {
            setState(() {
              _selected.value = !_selected.value;
            });
          },
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all(
              isSelected ? Colors.blue : Colors.grey,
            ),
            foregroundColor: MaterialStateProperty.all(Colors.white),
            textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
          ),
          child: Text('Button'),
        );
      },
    );
  }
}

在上述代码中,我们定义了一个 MyStatefulButton,它包含了一个 ValueNotifier<bool>,用来表示按钮的选中状态。在按钮选中时,我们可以自定义按钮的样式。在 build 方法中,我们使用 ValueListenableBuilder 来监听选中状态的变化,并根据选中状态来更新按钮的样式。

6.Button Bar

如果你需要创建一个按钮组,可以使用 ButtonBar。ButtonBar 是一个将多个按钮组合在一起的控件,它支持垂直或水平排列按钮,并且可以根据需要自动对齐按钮。

举个例子,我们可以创建一个带有多个按钮的 ButtonBar:

ButtonBar(
  alignment: MainAxisAlignment.center,
  children: [
    ElevatedButton(
      onPressed: () {},
      child: Text('Button 1'),
    ),
    ElevatedButton(
      onPressed: () {},
      child: Text('Button 2'),
    ),
    ElevatedButton(
      onPressed: () {},
      child: Text('Button 3'),
    ),
  ],
)

在上述代码中,我们使用 ButtonBar 创建了一个带有三个 ElevatedButton 的按钮组。我们将 alignment 属性设置为 MainAxisAlignment.center,使按钮水平居中对齐。

自定义按钮形状

如果你需要创建一个自定义形状的按钮,可以使用 ShapeBorder。ShapeBorder 是一个抽象类,它定义了一个形状。我们可以继承 ShapeBorder 来创建自定义形状。

举个例子,我们可以创建一个圆形按钮:

class CircleBorder extends ShapeBorder {
  const CircleBorder();

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.zero;

  @override
  Path
getInnerPath(Rect rect, {TextDirection? textDirection}) {
return getOuterPath(rect, textDirection: textDirection);
}

@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
return Path()
..addOval(rect);
}

@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}

@override
ShapeBorder scale(double t) {
return CircleBorder();
}
}

在上述代码中,我们定义了一个 CircleBorder 类,它继承自 ShapeBorder。在 getOuterPath 方法中,我们使用 Path.addOval 方法创建了一个圆形的 Path。在 paint 方法中,我们什么都不做,因为我们只是想创建一个圆形形状的按钮。

接下来,我们可以使用 CircleBorder 创建一个圆形的按钮:

ElevatedButton(
  onPressed: () {},
  child: Text('Button'),
  style: ButtonStyle(
    shape: MaterialStateProperty.all(CircleBorder()),
  ),
)

在上述代码中,我们使用 CircleBorder 创建了一个圆形的按钮。我们将 shape 属性设置为 MaterialStateProperty.all(CircleBorder()),表示按钮的形状是一个 CircleBorder。

7.自定义按钮效果

如果你需要创建一个自定义效果的按钮,可以使用 InkResponse。InkResponse 是一个将水波纹效果添加到任何 Widget 的控件,它支持自定义水波纹颜色、形状等属性。

举个例子,我们可以创建一个带有自定义水波纹效果的按钮:

InkResponse(
  onTap: () {},
  child: Container(
    padding: EdgeInsets.all(16),
    child: Text('Button'),
    decoration: BoxDecoration(
      color: Colors.grey,
      borderRadius: BorderRadius.circular(8),
    ),
  ),
  splashColor: Colors.red,
  highlightColor: Colors.yellow,
  borderRadius: BorderRadius.circular(8),
)

在上述代码中,我们使用 InkResponse 创建了一个带有自定义水波纹效果的按钮。在 onTap 回调中,我们处理按钮的点击事件。我们将 child 属性设置为一个 Container,用来包含按钮的文本。我们将 decoration 属性设置为 BoxDecoration,用来定义按钮的背景颜色和圆角。我们将 splashColor 和 highlightColor 属性分别设置为 Colors.red 和 Colors.yellow,用来定义水波纹的颜色。最后,我们将 borderRadius 属性设置为 BorderRadius.circular(8),用来定义按钮的圆角半径。

总结

通过本文的介绍,我们学习了 ButtonStyle 的基本用法和高级用法,包括使用 MaterialStateProperty、StatefulButton、ButtonBar、自定义按钮形状和自定义按钮效果。通过这些技巧,我们可以更好地定制 Flutter 控件的样式,从而创建更好的用户体验。

写作不易,留个关注,收藏哦!!文章来源地址https://www.toymoban.com/news/detail-786349.html

到了这里,关于Flutter 中的 ButtonStyle 和 MaterialStateProperty:深入了解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入理解 Flutter 图片加载原理 | 京东云技术团队

    随着Flutter稳定版本逐步迭代更新,京东APP内部的Flutter业务也日益增多,Flutter开发为我们提供了高效的开发环境、优秀的跨平台适配、丰富的功能组件及动画、接近原生的交互体验,但随之也带来了一些OOM问题,通过线上监控信息和Observatory工具结合分析我们发现问题的原因

    2024年02月12日
    浏览(36)
  • Flutter状态管理 — 探索Flutter中的状态

    前言 随着响应式编程的理念Flutter被大众所了解以来,状态管理一直是一个引人深思的话题。如果想要学习好Flutter这样的响应式的编程框架就一定是离不开状态管理的。我遇到过很多没有了解过响应式编程框架的,或者从事后端开发,自己想用Flutter写个app玩玩的朋友,一上来

    2024年02月09日
    浏览(40)
  • Flutter笔记:关于Flutter中的大文件上传(上)

    Flutter笔记 关于Flutter中的大文件上传(上) 大文件上传背景与 Flutter 端实现文件分片传输 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/134302751 本系列上下两篇文章,包括 Flutter 端和 Django 端(后

    2024年02月03日
    浏览(53)
  • Flutter系列文章-Flutter在实际业务中的应用

    1. 跨平台开发: 在移动应用开发中,面对不同的平台(iOS和Android),我们通常需要编写两套不同的代码。而Flutter通过一套代码可以构建适用于多个平台的应用,大大提高了开发效率,降低了维护成本。 2. 混合开发: 在一些已有的原生应用中,引入Flutter可以用于开发某些特

    2024年02月11日
    浏览(44)
  • Flutter 环境变量配置和flutter doctor中的错误解决

    一、环境变量 右键点击 我的电脑-属性:然后找到环境变量   1.Android的SDK不在C盘的话需要额外配这个到用户环境变量: 2.然后在系统变量:Path 中添加一条这样的值         D:Flutterflutterbin                  这个值写flutter包解压的实际地址即可  3.在系统变量中添

    2023年04月26日
    浏览(44)
  • flutter:animate_do(flutter中的Animate.css)

    做过web开发的应该大部分人都知道 Animate.css ,它为开发者提供了一系列预定义的动画效果,可以通过简单的CSS类来实现各种动画效果。而 animate_do 相当于flutter中的 Animate.css ,它提供了很多定义好的动画效果 官方地址 https://pub-web.flutter-io.cn/packages/animate_do 安装 示例一 示例2 示

    2024年02月16日
    浏览(51)
  • Flutter中的Firebase:如何使用Flutter连接Firebase数据库

    作者:禅与计算机程序设计艺术 作为一名人工智能专家,程序员和软件架构师,我经常会被Flutter的技术魅力所吸引。Flutter作为Kotlin和JavaScript的混合编程语言,具有高效、快速、美观的开发体验。同时,Flutter也是Google推荐的跨平台移动应用开发首选。而在Flutter中,Firebase数

    2024年02月09日
    浏览(43)
  • Flutter调优--深入探究MediaQuery引起界面Rebuild的原因及解决办法

    我们可以通过 MediaQuery.of(context) 方法获取到一些设备和系统的相关信息,比如状态栏的高度、当前是否是黑暗模式等等,使用起来相当方便,但是也要注意可能引起的页面rebuild问题。本文会介我们可以通过 MediaQuery.of(context) 方法获取到一些设备和系统的相关信息,比如状态栏

    2024年02月06日
    浏览(36)
  • Flutter中的基本组件

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Text组件(简单样式文本框组件)用于显示简单的样式文本,它的常用属性如下表所示。 TextStyle的常用属性如下表所示。 RichText组件(丰富文本组件)是Flutter提供的一个可以展示多种样式的Widget,经常应用

    2024年02月04日
    浏览(34)
  • Flutter中的Tree

    一、Widget 组合类(Composite Widgets) 如Container、Scaffold、MaterialApp等,以及通过继承StatelessWidget和StatefulWidget的类。 代理类(Proxy Widgets) 如InheritedWidget,这是一种功能型组件,可以高效快捷地实现共享数据的跨组件传递; InheritedWidget是一个代理类Widget,主要用于在Descendant Wi

    2024年02月03日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包