Flutter 问题系列第 49 篇在 Flutter 中如何给组件设置背景色圆角边框形状阴影渐变色背景图片等效果

Posted Allen Su

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 问题系列第 49 篇在 Flutter 中如何给组件设置背景色圆角边框形状阴影渐变色背景图片等效果相关的知识,希望对你有一定的参考价值。

这是【Flutter 问题系列第 49 篇】,如果觉得有用的话,欢迎关注专栏。

博主目前使用的 Flutter 版本:2.2.3,Dart 版本:2.13.4,android Studio 版本:Arctic Fox 2020.3.1 Pathc 3

一:Decoration,装饰类

如果你想给 Flutter 中的组件设置背景色、圆角、边框、形状、阴影、渐变、背景图片等,也就是想"装饰"这个组件,在 Flutter 中,通过 Decoration 抽象类给组件装饰。

在官方文档中,也说到了继承于 Decoration 类的分别有

装饰子类主要作用
BoxDecoration背景色、圆角、边框、形状、阴影、渐变色、背景图片等
ShapeDecoration对四边或任一边设置颜色,宽度、设置圆角矩形边界、圆形边界、斜切的矩形边界
FlutterLogoDecorationFlutter 的 Logo 装饰
UnderlineTabIndicator下划线标签指示器

因为 Container 组件有一个装饰属性 decoration,所以后面的都以 Container 组件为例,对每一个装饰子类进行解释说明,设置 Container 的宽度为 280,height 为 120。

二:BoxDecoration,盒子装饰

顾名思义,装饰的是盒子类型的,先来看一下 BoxDecoration 类的构造函数

const BoxDecoration(
   this.color, // 背景色
   this.image, // 背景图片
   this.border, // 边框的颜色和宽度
   this.borderRadius, // 圆角
   this.boxShadow, // 阴影
   this.gradient, // 渐变色
   this.backgroundBlendMode, // 混合 Mode
   this.shape = BoxShape.rectangle, // 形状,默认矩形
  )

下面我以修改单个属性后 Container 前后变化为例,对 BoxDecoration 的每个属性进行解释说明。


color,设置背景色

BoxDecoration 的属性 color 可以设置背景色,因为我并没有对 Container 设置颜色,所以它原来是透明的,接下来我们让盒子的背景色设置为粉红色

如下代码所示

decoration: BoxDecoration(
  color: Colors.pink
),

效果图如下所示


borderRadius,设置圆角

BoxDecoration 的属性 borderRadius 可以设置圆角

一:设置所有边的圆角

如下代码所示

decoration: BoxDecoration(
  borderRadius: BorderRadius.all(Radius.circular(100)) // 设置所有边的圆角
),

效果图如下所示

二:设置某边的圆角

如果你想对垂直或者水平方向上的边设置圆角,或者对任意一边设置圆角也是可以的,如下代码所示

decoration: BoxDecoration(
  color: Colors.pink,
  
  // 01 设置垂直方向上的圆角。top 影响左上和右上边的圆角、bottom 影响左下和右下边的圆角
  borderRadius: BorderRadius.vertical(top: Radius.circular(100),bottom: Radius.circular(100),
  ),
  
  // 02 设置水平方向上的圆角。left 影响左上和左下边的圆角、right 影响右上和右下边的圆角
  borderRadius: BorderRadius.horizontal(left: Radius.circular(100), right: Radius.circular(100))

  // 03 对任意一边设置圆角。topLeft 左上、topRight 右上、bottomLeft 左下、bottomRight 右下
  borderRadius: BorderRadius.only(
 	topLeft: Radius.circular(100),topRight: Radius.circular(100),
    bottomLeft: Radius.circular(100),bottomRight: Radius.circular(100),
  ),
),

这里我以 03 修改左上和右下边的圆角为例,修改前后的对比图如下所示


border,设置边框

BoxDecoration 的属性 border 可以设置边框

一:设置所有边的边框

如下代码所示

decoration: BoxDecoration(
  // width 边框的宽度,color 边框的颜色
  border: Border.all(width: 2, color: Colors.yellow),
),

效果图如下

二:设置某边的边框

如果你想对垂直或者水平方向上的边设置边框,或者对任意一边设置边框也是可以的,如下代码所示

decoration: BoxDecoration(
  // 01 设置垂直或水平方向上的边框
  border: Border.symmetric(
    vertical: BorderSide(width: 2, color: Colors.black), // 垂直方向边框(影响 top 和 bottom)
    horizontal: BorderSide(width: 2, color: Colors.yellow),// 水平方向边框(影响 left 和 right)
  ),

  // 02 对任意一边设置边框。
  border: Border(
    top: BorderSide(width: 2, color: Colors.yellow),
    bottom: BorderSide(width: 2, color: Colors.black),
    left: BorderSide(width: 2, color: Colors.white),
    right: BorderSide.none, // 右边不设置边框
  ),
),

这里我以 02 修改上边、下边和左边的边框,右边框不做修改为例,修改前后的对比图如下所示


shape,设置形状

BoxDecoration 的属性 shape 可以设置形状

支持两种形状,默认为矩形,即 BoxShape.rectangle,还可以设置为圆形,即 BoxShape.circle,如下代码所示

decoration: BoxDecoration(
  shape: BoxShape.circle,
),

效果图如下

关于 shape,我根据官方文档总结以下两点

  • 当设置 shape 为圆形时,不能再对 borderRadius 属性进行操作,否则会报错。
  • 虽然可以设置 shape 的值为圆形,但这并不是说可以用这个参数来裁剪组件,因为这会以性能为代价,如果需要裁剪,可以用组件 ClipRect、ClipRRect,、ClipPath

boxShadow,设置阴影

BoxDecoration 的属性 boxShadow 可以设置阴影

如下代码所示

decoration: BoxDecoration(
  boxShadow: [
    BoxShadow(
      color: Colors.blue, // 阴影的颜色
      spreadRadius: 0, // 阴影的大小
      blurRadius: 0, // 阴影模糊度的大小,值越大阴影范围也越大,但也更透明
      offset: Offset(0, 0), // 阴影分别在水平和垂直方向上的偏移量
    ),
  ],
),

下面我分别依次改变

阴影的颜色 color(透明→蓝色)和阴影的大小 spreadRadius(0→3)、阴影模糊度的大小 blurRadius(0→10)、阴影的偏移量 offset (0,0)→(5,5)。

如下图所示

通过对比图可以很直观的看出来,当某个参数发生改变时影响了什么。

boxShadow 类型是 List<BoxShadow>,修改一个阴影明白了,再添加其它的也是同理了。


gradient,设置渐变色

BoxDecoration 的属性 gradient 可以设置渐变色,gradient 的类型为 Gradient,而 Gradient 有三个子类,分别是

  • LinearGradient,线性渐变,点击查看 官网文档 详情
  • SweepGradient,扫描渐变,点击查看 官网文档 详情
  • RadialGradient,环形渐变,点击查看 官网文档 详情

这里以使用相对较多的线性变色 LinearGradient 为例,说下设置渐变色的常用参数有哪些。

如下代码所示

decoration: BoxDecoration(
  gradient: LinearGradient(
    colors: [Colors.red, Colors.blue, Colors.yellow], // 设置有哪些渐变色
    begin: Alignment.centerLeft, // 渐变色开始的位置,默认 centerLeft
    end: Alignment.centerRight, // 渐变色结束的位置,默认 centerRight
    stops: [0, 0.5, 1], // 颜色值梯度,取值范围[0,1],长度要和 colors 的长度一样
  ),
),

效果图如下

关于扫描渐变 SweepGradient 和环形渐变 RadialGradient 不再做详细的解释了,这里只看下效果吧

先看下扫描渐变 SweepGradient,以 Colors.red, Colors.blue 为一组,在 colors 属性中循环 6 次,效果图如下

再看下环形渐变 RadialGradien,这里设置 colors 为

colors: [Colors.red, Colors.green, Colors.purple, Colors.green, Colors.red, Colors.orange],并同时设置形状 shape 为圆形,效果图如下所示


image,设置背景图片

BoxDecoration 的属性 image 可以设置背景图片,网络或者本地的图片皆可。

一:设置网络图片为背景

如下代码所示

decoration: BoxDecoration(
  image: DecorationImage(
  	image: NetworkImage("https://profile.csdnimg.cn/E/E/8/1_qq_42351033"), // 图片地址
  	fit: BoxFit.scaleDown, // 图片填充方式,默认 scaleDown
  ),
),

效果图如下所示

二:设置本地图片为背景

如下代码所示

decoration: BoxDecoration(
  image: DecorationImage(image: AssetImage("assets/images/game.png")), // 本地图片路径
),

下图中第二张有背景色,第三张把背景色给去掉了


三:ShapeDecoration,形状装饰

形状装饰,构造函数如下

const ShapeDecoration(
  this.color, // 背景色
  this.image, // 背景图片
  this.gradient, // 渐变色
  this.shadows, // 阴影
  required this.shape, // 形状
)

除参数 shape 以外,其它参数都和 BoxDecoration 一样,下面重点来说下 shape 参数。

shape 类型为 ShapeBorder,所以以下所填的参数虽然不直接是 ShapeBorder,但都是其子类。

Border.all,设置所有边的颜色和宽度

decoration: ShapeDecoration(
  shape: Border.all(color: Colors.blue, width: 2),
)

效果图如下

其实这和 OutlineInputBorder 的效果是差不多的,只不过 OutlineInputBorder 还可以设置边角。


Border,设置任一边的颜色和宽度

decoration: ShapeDecoration(
  shape: Border(
    top: BorderSide(color: Colors.red, width: 2),
    bottom: BorderSide(color: Colors.blue, width: 2),
    left: BorderSide(color: Colors.green, width: 2),
    right: BorderSide(color: Colors.yellow, width: 2),
  ),
 )

效果图如下

如果只设置了 bottom 属性,效果就等同于 UnderlineInputBorder了。


RoundedRectangleBorder,设置圆角矩形边界

decoration: ShapeDecoration(
  shape: RoundedRectangleBorder(
  borderRadius: BorderRadius.circular(100),
  side: BorderSide(color: Colors.blue, width: 2),
  ),
)

效果图如下

当 borderRadius 设置的很大时,和球场边界 StadiumBorder 的效果是一样的。


CircleBorder,设置圆形边界

decoration: ShapeDecoration(
  shape: CircleBorder(
    side: BorderSide(color: Colors.blue, width: 2),
  ),
)

效果图如下


BeveledRectangleBorder,斜切的矩形边界

decoration: ShapeDecoration(
  shape: BeveledRectangleBorder(
    borderRadius: BorderRadius.circular(30),
    side: BorderSide(color: Colors.blue, width: 2),
  ),
)

效果图如下


四:FlutterLogoDecoration,Flutter 的 Logo 装饰

这个实际开发中几乎用不到,是关于 Flutter 的 Logo 的装饰,参数就三个,构造函数如下

const FlutterLogoDecoration(
  this.textColor = const Color(0xFF757575), // Flutter 文字颜色
  this.style = FlutterLogoStyle.markOnly, // Logo 显示的方向
  this.margin = EdgeInsets.zero, // 外边距
)

这里设置 Logo 显示方向为 FlutterLogoStyle.horizontal ,效果图如下


五:UnderlineTabIndicator,标签指示器

标签指示器,这个可以认为是添加下划线的,如 TabBar 底部的指示器,参数就两个,构造函数如下

const UnderlineTabIndicator(
  this.borderSide = const BorderSide(width: 2.0, color: Colors.white), // 下划线边框
  this.insets = EdgeInsets.zero, // 下划线边距
)

效果图如下


终于写完了,几乎用了一天的时间,其实这篇博客几个月前就想写了,但我知道写起来会很费时间。

昨天一同事问如何设置盒子阴影时我没答上来,所以趁着周末把应该几个月前就写的给补上。

你的问题得到解决了吗?欢迎在评论区留言。

赠人玫瑰,手有余香,如果觉得文章不错,希望可以给个一键三连,感谢。


结束语

技术是一点一点积累的,大神也不是一天就可以达到的。原地不动就是退步,所以每天进步一点点。

最后,附上一句格言:"好学若饥,谦卑若愚",望共勉。

以上是关于Flutter 问题系列第 49 篇在 Flutter 中如何给组件设置背景色圆角边框形状阴影渐变色背景图片等效果的主要内容,如果未能解决你的问题,请参考以下文章

动手编写你的第一个 Flutter 应用

[Flutter] 写第一个 Flutter app,part1 要点

第11期Kotlin和Flutter,全都给你

Google官宣:Flutter全平台称霸

在 webview_flutter 中启用捏合和缩放,在哪里添加代码片段 [this.webView.getSettings().setBuiltInZoomControls(true);]

Flutter的安装与设置(第一节)