build method

Widget build()

最终构建方法 - 一次性创建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;
}