【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 对四边或任一边设置颜色,宽度、设置圆角矩形边界、圆形边界、斜切的矩形边界
FlutterLogoDecoration Flutter 的 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, // 下划线边距
})

效果图如下


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

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

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

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


结束语

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

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>