You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现两个圆角两个直切角的TextFormField输入框

Flutter实现双圆角+双直切角TextFormField方案

默认InputDecoration提供的OutlineInputBorder仅支持圆角配置,无法直接实现直切角效果,你可以通过自定义InputBorder子类的方式实现需求,该方案可以完整适配输入框的聚焦、失焦、报错等内置状态,无需额外嵌套容器修改样式。

完整实现步骤

第一步:自定义直切角边框类

继承InputBorder重写路径绘制逻辑,自定义角的圆角/直切属性:

class CustomCutCornerInputBorder extends InputBorder {
  final double borderRadius;
  final double cutCornerSize;
  final Color borderColor;
  final double borderWidth;

  const CustomCutCornerInputBorder({
    super.borderSide,
    required this.borderRadius,
    required this.cutCornerSize,
    required this.borderColor,
    this.borderWidth = 1,
  });

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.all(borderWidth);

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    return getOuterPath(rect.deflate(borderWidth), textDirection: textDirection);
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    final path = Path();
    // 示例配置:左上角+右下角为直切角,右上角+左下角为圆角,可按需修改角的属性
    // 起点:左上角切角右端点
    path.moveTo(rect.left + cutCornerSize, rect.top);
    // 上边缘到右上角圆角起点
    path.lineTo(rect.right - borderRadius, rect.top);
    // 右上角圆角
    path.arcToPoint(
      Offset(rect.right, rect.top + borderRadius),
      radius: Radius.circular(borderRadius),
    );
    // 右边缘到右下角切角上端点
    path.lineTo(rect.right, rect.bottom - cutCornerSize);
    // 右下角切角
    path.lineTo(rect.right - cutCornerSize, rect.bottom);
    // 下边缘到左下角圆角起点
    path.lineTo(rect.left + borderRadius, rect.bottom);
    // 左下角圆角
    path.arcToPoint(
      Offset(rect.left, rect.bottom - borderRadius),
      radius: Radius.circular(borderRadius),
    );
    // 左边缘到左上角切角下端点
    path.lineTo(rect.left, rect.top + cutCornerSize);
    // 闭合左上角切角
    path.lineTo(rect.left + cutCornerSize, rect.top);
    return path;
  }

  @override
  void paint(Canvas canvas, Rect rect, {
    double? gapStart,
    double gapExtent = 0.0,
    double gapPercentage = 0.0,
    TextDirection? textDirection,
  }) {
    final paint = Paint()
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = borderWidth;
    canvas.drawPath(getOuterPath(rect), paint);
  }

  @override
  bool get isOutline => true;

  @override
  InputBorder copyWith({BorderSide? borderSide}) {
    return CustomCutCornerInputBorder(
      borderSide: borderSide ?? this.borderSide,
      borderRadius: borderRadius,
      cutCornerSize: cutCornerSize,
      borderColor: borderColor,
      borderWidth: borderWidth,
    );
  }

  @override
  ShapeBorder scale(double t) {
    return CustomCutCornerInputBorder(
      borderSide: borderSide.scale(t),
      borderRadius: borderRadius * t,
      cutCornerSize: cutCornerSize * t,
      borderColor: borderColor,
      borderWidth: borderWidth * t,
    );
  }
}

第二步:替换原有InputDecoration配置

把原配置中的OutlineInputBorder替换为自定义边框即可:

const InputDecoration kInputStringFields = InputDecoration(
  hintStyle: TextStyle(
    fontFamily: kBarlowFont,
    fontSize: 16.0,
  ),
  fillColor: kInputStringFieldColor,
  filled: true,
  contentPadding: EdgeInsets.only(left: 20.0),
  // 配置各状态下的自定义边框
  border: CustomCutCornerInputBorder(
    borderRadius: 20.0,
    cutCornerSize: 8.0, // 可按需调整直切角的尺寸
    borderColor: Colors.transparent,
    borderWidth: 0,
  ),
  enabledBorder: CustomCutCornerInputBorder(
    borderRadius: 20.0,
    cutCornerSize: 8.0,
    borderColor: Colors.transparent,
    borderWidth: 0,
  ),
  focusedBorder: CustomCutCornerInputBorder(
    borderRadius: 20.0,
    cutCornerSize: 8.0,
    borderColor: Colors.transparent,
    borderWidth: 0,
  ),
);

效果调整说明

修改getOuterPath方法内的路径绘制逻辑,即可自由切换任意角为圆角或直切角,调整borderRadius和cutCornerSize参数可以修改圆角大小、切角的尺寸,适配你的设计需求。

内容的提问来源于stack exchange,提问作者Zelf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 17:15:04