Flutter系列重学Container示例详解
SoaringHeart 人气:0一、Container 简介
flutter 开发中最核心的是用最少的组件(层次)完成功能开发;Container 前端的盒子模型实现,类似 div 标签,掌握其他组件前,深入学习理解 Container 的使用是必要的。
Container
是一个组合类容器,由DecoratedBox
、ConstrainedBox、Transform
、Padding
、Align
等组件组合的一个多功能容器,所以我们只需通过一个Container
组件可以实现同时需要装饰、变换、约束限制的场景。
二、示例
- 示例包含透明度,背景装饰,前景装饰,child 模糊度,红色部分是 child;
buildSection() { return Opacity( opacity: 1, child: Container( margin: EdgeInsets.all(20), padding: EdgeInsets.all(20), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(20)), gradient: LinearGradient( colors: [Colors.green, Colors.yellow], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), boxShadow: [ BoxShadow( color: Colors.red.withOpacity(0.5), spreadRadius: 5, blurRadius: 7, offset: Offset(0, 3), // changes position of shadow ), ], image: DecorationImage( image: NetworkImage('https://tenfei02.cfp.cn/creative/vcg/800/new/VCG21409037867.jpg'), fit: BoxFit.cover, ), ), foregroundDecoration: BoxDecoration( color: Colors.yellow, border: Border.all(color: Colors.green, width: 5), borderRadius: BorderRadius.all(Radius.circular(400)), image: DecorationImage( image: NetworkImage('http://pic.616pic.com/bg_w1180/00/04/08/G5Bftx5ZDI.jpg'), fit: BoxFit.cover, ), ), child: BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( constraints: BoxConstraints.expand(), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(20)), color: Colors.red, ), child: Text('VCG21409037867'), ), ), ), ); }
- 实现背景图 background-repeat 显示,flutter支持四种类型:
enum ImageRepeat { repeat, repeatX, repeatY, noRepeat, }
这里以第一种 ImageRepeat.repeat 为例:
Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/img_update.png'), repeat: ImageRepeat.repeat, alignment: Alignment.topLeft, ) ), child: Container( constraints: BoxConstraints.expand(), child: OutlinedButton( onPressed: () { print("ImageRepeat.repeat"); }, child: Text('ImageRepeat.repeat', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.red), ), ), ), ),
transform && alignment
Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/img_update.png'), repeat: ImageRepeat.repeat, alignment: Alignment.topLeft, ) ), transform: Matrix4.rotationZ(.2),//变化 alignment: Alignment.centerRight, //卡片文字对齐 child: Text( "5.20", style: TextStyle(color: Colors.red, fontSize: 40.0), ), ),
三、源码分析
class Container extends StatelessWidget { Container({ Key? key, this.alignment, this.padding, this.color, this.decoration, this.foregroundDecoration, double? width, double? height, BoxConstraints? constraints, this.margin, this.transform, this.transformAlignment, this.child, this.clipBehavior = Clip.none, }):super(key: key); // 子项 final Widget? child; // 内边距 final EdgeInsetsGeometry? padding; // 背景色,和 decoration 只能二选一 final Color? color; // 背景装饰 final Decoration? decoration; // 前景装饰(在 child 之上) final Decoration? foregroundDecoration; // 约束条件 final BoxConstraints? constraints; // 外边距 final EdgeInsetsGeometry? margin; // 变化 final Matrix4? transform; // 变化之后 child 对齐方式 final AlignmentGeometry? transformAlignment; // 裁剪方式 final Clip clipBehavior; EdgeInsetsGeometry? get _paddingIncludingDecoration { if (decoration == null || decoration!.padding == null) return padding; final EdgeInsetsGeometry? decorationPadding = decoration!.padding; if (padding == null) return decorationPadding; return padding!.add(decorationPadding!); } @override Widget build(BuildContext context) { Widget? current = child; if (child == null && (constraints == null || !constraints!.isTight)) { current = LimitedBox( maxWidth: 0.0, maxHeight: 0.0, child: ConstrainedBox(constraints: const BoxConstraints.expand()), ); } if (alignment != null) current = Align(alignment: alignment!, child: current); final EdgeInsetsGeometry? effectivePadding = _paddingIncludingDecoration; if (effectivePadding != null) current = Padding(padding: effectivePadding, child: current); if (color != null) current = ColoredBox(color: color!, child: current); if (clipBehavior != Clip.none) { assert(decoration != null); current = ClipPath( clipper: _DecorationClipper( textDirection: Directionality.maybeOf(context), decoration: decoration!, ), clipBehavior: clipBehavior, child: current, ); } if (decoration != null) current = DecoratedBox(decoration: decoration!, child: current); if (foregroundDecoration != null) { current = DecoratedBox( decoration: foregroundDecoration!, position: DecorationPosition.foreground, child: current, ); } if (constraints != null) current = ConstrainedBox(constraints: constraints!, child: current); if (margin != null) current = Padding(padding: margin!, child: current); if (transform != null) current = Transform(transform: transform!, alignment: transformAlignment, child: current); return current!; } ... }
源码很简单,组件层层包裹,但是我们必须清楚每一个参数的作用和使用场景。它可以帮你用更少的层级完成功能,这很重要。
加载全部内容