build method
最终构建方法 - 一次性创建Container
Implementation
Widget build() {
// 构建 BoxDecoration
BoxDecoration? decoration;
// 处理边框:合并 Border 和 BorderDirectional
Border? finalBorder = _border;
if (_borderDirectional != null) {
// 如果有 BorderDirectional,需要与现有 Border 合并
// BoxDecoration 不支持 BorderDirectional,我们需要根据 TextDirection 转换
// 使用 Builder 来获取当前的 TextDirection
final borderDir = _borderDirectional!;
final textDir = _textDirection;
// 根据 TextDirection 决定 start/end 对应 left/right
BorderSide leftSide = borderDir.start;
BorderSide rightSide = borderDir.end;
// 如果指定了 TextDirection 且为 RTL,交换 left 和 right
if (textDir == TextDirection.rtl) {
leftSide = borderDir.end;
rightSide = borderDir.start;
}
// 合并边框
if (_border != null) {
finalBorder = Border(
top: _border!.top,
bottom: _border!.bottom,
left: borderDir.start.width > 0 ? leftSide : _border!.left,
right: borderDir.end.width > 0 ? rightSide : _border!.right,
);
} else {
finalBorder = Border(
top: borderDir.top,
bottom: borderDir.bottom,
left: leftSide,
right: rightSide,
);
}
}
// 应用边框透明度
if (_borderOpacity != null && finalBorder != null) {
finalBorder = Border(
top: BorderSide(
color: finalBorder.top.color.withValues(alpha: _borderOpacity!),
width: finalBorder.top.width,
),
bottom: BorderSide(
color: finalBorder.bottom.color.withValues(alpha: _borderOpacity!),
width: finalBorder.bottom.width,
),
left: BorderSide(
color: finalBorder.left.color.withValues(alpha: _borderOpacity!),
width: finalBorder.left.width,
),
right: BorderSide(
color: finalBorder.right.color.withValues(alpha: _borderOpacity!),
width: finalBorder.right.width,
),
);
}
// 应用背景透明度
Color? finalBackgroundColor = _backgroundColor;
if (_backgroundOpacity != null && finalBackgroundColor != null) {
finalBackgroundColor = finalBackgroundColor.withValues(alpha: _backgroundOpacity!);
}
// 如果有背景图片,需要创建 DecorationImage
DecorationImage? decorationImage;
if (_backgroundImage != null) {
decorationImage = DecorationImage(
image: _backgroundImage!.image,
fit: _backgroundSize,
alignment: _backgroundPosition ?? Alignment.center,
repeat: _backgroundRepeat ?? ImageRepeat.noRepeat,
);
}
if (finalBackgroundColor != null ||
finalBorder != null ||
_borderRadius != null ||
_boxShadow != null ||
_gradient != null ||
decorationImage != null) {
decoration = BoxDecoration(
color: _gradient == null ? finalBackgroundColor : null, // 如果有渐变就不设置color
border: finalBorder,
borderRadius: _borderRadius,
boxShadow: _boxShadow,
gradient: _gradient,
backgroundBlendMode: _backgroundBlendMode,
image: decorationImage,
shape: _shape,
);
}
// 计算边框宽度(用于 box-sizing)
double borderWidthHorizontal = 0.0;
double borderWidthVertical = 0.0;
if (finalBorder != null) {
borderWidthHorizontal = finalBorder.left.width + finalBorder.right.width;
borderWidthVertical = finalBorder.top.width + finalBorder.bottom.width;
}
// 计算 padding 尺寸(用于 box-sizing)
double paddingWidthHorizontal = 0.0;
double paddingWidthVertical = 0.0;
if (_padding != null) {
if (_padding is EdgeInsets) {
final padding = _padding as EdgeInsets;
paddingWidthHorizontal = padding.left + padding.right;
paddingWidthVertical = padding.top + padding.bottom;
} else if (_padding is EdgeInsetsDirectional) {
final padding = _padding as EdgeInsetsDirectional;
paddingWidthHorizontal = padding.start + padding.end;
paddingWidthVertical = padding.top + padding.bottom;
}
}
// 应用 box-sizing:如果 content-box,需要调整 width/height
double? adjustedWidth = _width;
double? adjustedHeight = _height;
if (!_boxSizingBorderBox) {
// content-box: width/height 不包含 padding 和 border
// Flutter Container 默认行为是 border-box,所以我们需要调整
// 如果设置了 width,实际容器宽度 = width + padding + border
if (_width != null) {
adjustedWidth = _width! + paddingWidthHorizontal + borderWidthHorizontal;
}
if (_height != null) {
adjustedHeight = _height! + paddingWidthVertical + borderWidthVertical;
}
}
// border-box (默认): width/height 已经包含 padding 和 border,不需要调整
// 构建约束
BoxConstraints? constraints = _constraints;
if (_minWidth != null || _maxWidth != null || _minHeight != null || _maxHeight != null) {
constraints = BoxConstraints(
minWidth: _minWidth ?? (constraints?.minWidth ?? 0),
maxWidth: _maxWidth ?? (constraints?.maxWidth ?? double.infinity),
minHeight: _minHeight ?? (constraints?.minHeight ?? 0),
maxHeight: _maxHeight ?? (constraints?.maxHeight ?? double.infinity),
);
}
// 如果有 BorderDirectional 且需要 RTL 支持,使用 Builder 获取 TextDirection
Widget container;
if (_borderDirectional != null && _textDirection == null) {
// 如果没有指定 TextDirection,使用 Builder 从上下文获取
container = Builder(
builder: (context) {
final textDir = Directionality.of(context);
Border? dynamicBorder = _border;
if (_borderDirectional != null) {
final borderDir = _borderDirectional!;
BorderSide leftSide = borderDir.start;
BorderSide rightSide = borderDir.end;
if (textDir == TextDirection.rtl) {
leftSide = borderDir.end;
rightSide = borderDir.start;
}
if (_border != null) {
dynamicBorder = Border(
top: _border!.top,
bottom: _border!.bottom,
left: borderDir.start.width > 0 ? leftSide : _border!.left,
right: borderDir.end.width > 0 ? rightSide : _border!.right,
);
} else {
dynamicBorder = Border(
top: borderDir.top,
bottom: borderDir.bottom,
left: leftSide,
right: rightSide,
);
}
}
// 重新计算 box-sizing(因为 dynamicBorder 可能与 finalBorder 不同)
double dynamicBorderWidthHorizontal = 0.0;
double dynamicBorderWidthVertical = 0.0;
if (dynamicBorder != null) {
dynamicBorderWidthHorizontal = dynamicBorder.left.width + dynamicBorder.right.width;
dynamicBorderWidthVertical = dynamicBorder.top.width + dynamicBorder.bottom.width;
}
double? dynamicAdjustedWidth = adjustedWidth;
double? dynamicAdjustedHeight = adjustedHeight;
if (!_boxSizingBorderBox) {
// content-box: 使用动态计算的边框宽度
if (_width != null) {
dynamicAdjustedWidth = _width! + paddingWidthHorizontal + dynamicBorderWidthHorizontal;
}
if (_height != null) {
dynamicAdjustedHeight = _height! + paddingWidthVertical + dynamicBorderWidthVertical;
}
}
BoxDecoration? dynamicDecoration = decoration;
if (dynamicBorder != finalBorder && dynamicDecoration != null) {
dynamicDecoration = BoxDecoration(
color: dynamicDecoration.color,
border: dynamicBorder,
borderRadius: dynamicDecoration.borderRadius,
boxShadow: dynamicDecoration.boxShadow,
gradient: dynamicDecoration.gradient,
backgroundBlendMode: dynamicDecoration.backgroundBlendMode,
image: dynamicDecoration.image,
shape: dynamicDecoration.shape,
);
}
return Container(
width: dynamicAdjustedWidth,
height: dynamicAdjustedHeight,
alignment: _alignment,
padding: _padding,
margin: _margin,
constraints: constraints,
transform: _transform,
transformAlignment: _transformAlignment,
decoration: dynamicDecoration ?? (dynamicBorder != null ? BoxDecoration(border: dynamicBorder) : null),
foregroundDecoration: _foregroundDecoration,
clipBehavior: _clipBehavior ?? Clip.none,
child: child,
);
},
);
} else {
container = Container(
width: adjustedWidth,
height: adjustedHeight,
alignment: _alignment,
padding: _padding,
margin: _margin,
constraints: constraints,
transform: _transform,
transformAlignment: _transformAlignment,
decoration: decoration,
foregroundDecoration: _foregroundDecoration,
clipBehavior: _clipBehavior ?? Clip.none,
child: child,
);
}
// 如果设置了 aspect ratio,使用 AspectRatio widget 包裹
if (_aspectRatio != null) {
container = AspectRatio(
aspectRatio: _aspectRatio!,
child: container,
);
}
// 如果设置了 mix-blend-mode,使用 ColorFiltered 实现
// 注意:Flutter 的 mix-blend-mode 需要通过 ColorFiltered 实现,但效果有限
// 对于复杂的混合模式,建议使用 BackdropFilter 或其他方式
if (_mixBlendMode != null) {
container = ColorFiltered(
colorFilter: ColorFilter.mode(Colors.transparent, _mixBlendMode!),
child: container,
);
}
// 如果设置了 imageFilter,使用 ImageFilter
if (_imageFilter != null) {
container = ImageFiltered(
imageFilter: _imageFilter!,
child: container,
);
}
// 如果设置了 colorFilter,使用 ColorFiltered
if (_colorFilter != null) {
container = ColorFiltered(
colorFilter: _colorFilter!,
child: container,
);
}
// 如果设置了 z-index,使用 Transform 来模拟层级
if (_zIndex != null) {
container = Transform(
transform: Matrix4.identity()..setTranslation(vm.Vector3(0.0, 0.0, _zIndex!.toDouble())),
child: container,
);
}
// 如果需要定位,包装成Positioned或PositionedDirectional
if (_isPositioned) {
// 如果使用了 start/end,使用 PositionedDirectional 以支持 RTL
if (_positionStart != null || _positionEnd != null) {
return PositionedDirectional(
top: _positionTop,
start: _positionStart,
end: _positionEnd,
bottom: _positionBottom,
width: _positionWidth,
height: _positionHeight,
child: container,
);
} else {
// 否则使用普通的 Positioned
return Positioned(
top: _positionTop,
right: _positionRight,
bottom: _positionBottom,
left: _positionLeft,
width: _positionWidth,
height: _positionHeight,
child: container,
);
}
}
return container;
}