【Flutter 组件集录】 DecoratedBox | 8 月更文挑战

前言:

这是我参与8月更文挑战的第 27 天,活动详情查看:8月更文挑战。为应掘金的八月更文挑战,我准备在本月挑选 31 个以前没有介绍过的组件,进行全面分析和属性介绍。这些文章将来会作为 Flutter 组件集录 的重要素材。希望可以坚持下去,你的支持将是我最大的动力~

| 本系列 | 组件文章 | 列表 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | 1.NotificationListener | 2.Dismissible | 3.Switch | | 4.Scrollbar | 5.ClipPath | 6.CupertinoActivityIndicator | | 7.Opacity | 8.FadeTransition | 9. AnimatedOpacity | | 10. FadeInImage | 11. Offstage | 12. TickerMode | | 13. Visibility | 14. Padding | 15. AnimatedContainer | | 16.CircleAvatar | 17.PhysicalShape | 18.Divider | | 19.Flexible、Expanded 和 Spacer | 20.Card | 21.SizedBox | | 22.ConstrainedBox | 23.Stack | 24.Positioned | | 25.OverflowBox | 26.SizedOverflowBox | 27. DecoratedBox |


1.认识 DecoratedBox 组件

DecoratedBox 组件可能单独使用的频率不是很高,因为它被集成在了 Container 组件中,但装饰的使用方式是共通的,源码中说 DecoratedBox 会在其孩子的前景或背景上绘制 Decoration 装饰对象。这说明 Decoration 才是装饰的重点,我们需要了解或自定义 Decoration


下面是 DecoratedBox 组件类的定义构造方法,可以看出它继承自 SingleChildRenderObjectWidget 。构造时必须传入尺寸 decoration 参数,可以传入 position 入参。

decoration 成员的类型是 Decoration ,表示装饰对象。position 成员的类型是 DecorationPosition 枚举,表示在前景绘制还是在背景绘制。

```dart final Decoration decoration; final DecorationPosition position;

enum DecorationPosition { background, foreground, } ```


2.认识 Decoration 及其子类

首先需要注意的是: Decoration 是一个抽象类,无法直接实例化使用。


Flutter 框架中提供了四个实现类,其中 BoxDecoration 是我们最常用的。

比如下面通过 BoxDecorationborderRadius 可以指定装饰的圆角,通过 color 指定填充的颜色。

```dart DecoratedBox( decoration: BoxDecoration( color: Colors.orangeAccent, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), bottomRight: Radius.circular(20), bottomLeft: Radius.circular(5), topRight: Radius.circular(5), ), ), child: buildContent(), );

Widget buildContent() { return SizedBox( width: 80, height: 80, child: Icon(Icons.android, size: 50, color: Colors.white), ); } ```

下面是 BoxDecoration 的构造方法,可以看出除了圆角和颜色,还有很多入参,比如背景图片边线阴影渐变形状等。

如下装饰,有红色史诗碎片那味了:

dart BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), bottomRight: Radius.circular(20), bottomLeft: Radius.circular(5), topRight: Radius.circular(5), ), border: Border.all(color: Colors.red, width: 2), image: DecorationImage( image: AssetImage('assets/images/bg_6.jpeg'), fit: BoxFit.cover, ), boxShadow: [ const BoxShadow( color: Colors.red, offset: Offset.zero, blurRadius: 2, spreadRadius: 2), ] ),


另外还有一个 ShapeDecoration 子类,顾名思义,它可以进行一些形状的处理。其中入参必须传入 ShapeBorder 类型的 shape 参数。关于 ShapeBorder ,详见 : 《Path在手,天下我有》

如下,通过一个 Flutter 自带的 CircleBorder 来测试一下:

dart DecoratedBox( position: DecorationPosition.background, decoration: ShapeDecoration( shape: CircleBorder(), shadows: const [BoxShadow( color: Colors.red, offset: Offset.zero, blurRadius: 2, spreadRadius: 2)], image: DecorationImage( image: AssetImage('assets/images/bg_6.jpeg'), fit: BoxFit.cover, ), ), child: buildContent(), );


3.自定义装饰

很多人问过我,如何加虚线边框。本质上就是在问如何通过绘制虚线,通过 DecoratedBox 装饰而已。在我发布的 dash_painter 包中有实现虚线装饰,就以此来讲述一下如何自定义装饰

dart dependencies: ... dash_painter: ^1.0.2

```dart import 'package:dashpainter/dashdecoration.dart';

DecoratedBox( decoration: DashDecoration( pointWidth: 2, step: 5, pointCount: 1, radius: Radius.circular(15), gradient: SweepGradient(colors: [ Colors.blue, Colors.red, Colors.yellow, Colors.green ])), child: buildContent(), );

Widget buildContent() { return SizedBox( width: 70, height: 70, child: Icon( Icons.add, color: Colors.orangeAccent, size: 40), ); } ```


下面看一下 DashDecoration 的源码实现,首先定义可配置的参数,通过构造函数初始化。

DashDecoration 中必须实现抽象方法 createBoxPainter ,返回一个 BoxPainter 对象。

然后继承 BoxPainter ,将配置对象传进来,在 paint 里画就完事了。本身流程很简单,关键在于如何绘制。在 《Flutter 绘制指南 - 妙笔生花》 小册中系统地介绍了 Flutter 绘制相关的基础知识,感兴趣的可以看一看。


4. DecoratedBox 的源码实现

DecoratedBox 继承自 SingleChildRenderObjectWidget ,内部维护 RenderDecoratedBox 渲染对象来实现装饰功能。


核心代码是下面的 paint 方法,执行绘制。其中 super.paint(context, offset); 是绘制子组件,可见 background 是在绘制孩子前绘制,也就是作为背景,孩子在前面。而 foreground 会覆盖在孩子前面,也就是前景。画笔是通过 _decoration#createBoxPainter 创建的,也就是那个 BoxPainter 对象。

那本文到这里就结束了,谢谢观看,明天见~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值