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

Flutter如何实现Container组件的自定义角部圆角效果

Flutter Container角部切角效果实现

Container角部效果参考

以下是两种可直接落地的实现方式,按需选择即可:

方案1:自定义ShapeBorder(无第三方依赖,推荐)

不需要引入任何外部包,通过自定义形状边框重绘路径即可实现,性能最好,灵活度最高。

  1. 先写自定义切角形状类:
import 'package:flutter/material.dart';

class NotchedCornerBorder extends ShapeBorder {
  final double notchSize; // 角部缺口尺寸
  final Color borderColor;
  final double borderWidth;

  const NotchedCornerBorder({
    this.notchSize = 12,
    this.borderColor = const Color(0xFFE0E0E0),
    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 + notchSize, rect.top);
    path.lineTo(rect.right - notchSize, rect.top);
    path.lineTo(rect.right, rect.top + notchSize);
    path.lineTo(rect.right, rect.bottom - notchSize);
    path.lineTo(rect.right - notchSize, rect.bottom);
    path.lineTo(rect.left + notchSize, rect.bottom);
    path.lineTo(rect.left, rect.bottom - notchSize);
    path.lineTo(rect.left, rect.top + notchSize);
    path.close();
    return path;
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
    if (borderWidth <= 0) return;
    final paint = Paint()
      ..color = borderColor
      ..strokeWidth = borderWidth
      ..style = PaintingStyle.stroke;
    canvas.drawPath(getOuterPath(rect), paint);
  }

  @override
  ShapeBorder scale(double t) {
    return NotchedCornerBorder(
      notchSize: notchSize * t,
      borderColor: borderColor,
      borderWidth: borderWidth * t,
    );
  }
}
  1. 直接在Container中使用:
Container(
  width: 240,
  height: 120,
  alignment: Alignment.center,
  decoration: ShapeDecoration(
    color: Colors.white,
    // 配置阴影效果
    shadows: const [
      BoxShadow(
        color: Colors.black12,
        blurRadius: 4,
        offset: Offset(0, 2),
      )
    ],
    shape: NotchedCornerBorder(
      notchSize: 18, // 调整这个值匹配设计图的缺口大小
      borderColor: Colors.blue,
      borderWidth: 2,
    ),
  ),
  child: const Text("切角容器内容"),
)

如果需要实现内凹圆角而非直切角,只要把getOuterPath里的直线绘制方法lineTo替换为quadraticBezierTo绘制圆弧路径即可;如果只需要单个/部分角做切角,对应删减路径绘制逻辑就行。

方案2:第三方包快速实现

不想手动绘制路径的话,可以直接用封装好的组件快速实现:

  1. 在pubspec.yaml中添加依赖:
dependencies:
  shape_of_view_null_safe: ^2.0.1
  1. 引入后直接使用:
ShapeOfView(
  shape: CutCornerShape(18), // 18为切角尺寸
  borderColor: Colors.blue,
  borderWidth: 2,
  child: Container(
    width: 240,
    height: 120,
    color: Colors.white,
    alignment: Alignment.center,
    child: const Text("第三方实现切角容器"),
  ),
)

调试技巧

  • 调整notchSize/切角尺寸参数,直到和参考图的角部比例完全一致
  • 如果容器内有点击事件,自定义Shape的方案会自动适配点击区域,不会出现边角空白区域也响应点击的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 11:01:41