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

如何在Flutter中创建如图所示的自定义箭头形状?

在Flutter中创建自定义箭头形状

要实现你需要的两种自定义箭头,推荐用以下两种灵活的方式:

方法一:使用CustomPainter直接绘制形状

通过自定义CustomPainter,可以精确控制箭头的每一个顶点,适合不需要添加子组件的纯形状需求。

自定义Painter类

class ArrowPainter extends CustomPainter {
  final Color color;
  final bool isStyleTwo; // 标记是样式1还是样式2

  ArrowPainter({required this.color, this.isStyleTwo = false});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = color
      ..style = PaintingStyle.fill;

    final path = Path();
    if (!isStyleTwo) {
      // 对应第一种箭头样式(左侧带缺口的右箭头)
      path.moveTo(0, 0);
      path.lineTo(size.width * 0.75, 0);
      path.lineTo(size.width, size.height / 2);
      path.lineTo(size.width * 0.75, size.height);
      path.lineTo(0, size.height);
      path.lineTo(0, size.height * 0.2);
      path.lineTo(size.width * 0.1, size.height / 2);
      path.lineTo(0, size.height * 0.8);
      path.close();
    } else {
      // 对应第二种箭头样式(左侧带三角的右箭头)
      path.moveTo(size.width * 0.2, 0);
      path.lineTo(size.width, 0);
      path.lineTo(size.width, size.height);
      path.lineTo(size.width * 0.2, size.height);
      path.lineTo(size.width * 0.4, size.height / 2);
      path.close();
    }

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return oldDelegate != this;
  }
}

使用Painter

在Widget树中直接调用:

// 样式1箭头
CustomPaint(
  size: const Size(120, 60), // 按需调整尺寸
  painter: ArrowPainter(color: Colors.blue),
)

// 样式2箭头
CustomPaint(
  size: const Size(120, 60),
  painter: ArrowPainter(color: Colors.green, isStyleTwo: true),
)

方法二:使用ClipPath裁剪容器

如果需要给箭头添加文字、图标或装饰(比如阴影、渐变),用ClipPath裁剪容器会更方便。

自定义Clipper类

class ArrowClipPath extends CustomClipper<Path> {
  final bool isStyleTwo;

  ArrowClipPath({this.isStyleTwo = false});

  @override
  Path getClip(Size size) {
    final path = Path();
    if (!isStyleTwo) {
      // 样式1路径
      path.moveTo(0, 0);
      path.lineTo(size.width * 0.75, 0);
      path.lineTo(size.width, size.height / 2);
      path.lineTo(size.width * 0.75, size.height);
      path.lineTo(0, size.height);
      path.lineTo(0, size.height * 0.2);
      path.lineTo(size.width * 0.1, size.height / 2);
      path.lineTo(0, size.height * 0.8);
      path.close();
    } else {
      // 样式2路径
      path.moveTo(size.width * 0.2, 0);
      path.lineTo(size.width, 0);
      path.lineTo(size.width, size.height);
      path.lineTo(size.width * 0.2, size.height);
      path.lineTo(size.width * 0.4, size.height / 2);
      path.close();
    }
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return oldClipper != this;
  }
}

使用ClipPath

可以给容器添加任意装饰和子组件:

// 样式1箭头容器(带阴影和文字)
ClipPath(
  clipper: ArrowClipPath(),
  child: Container(
    width: 120,
    height: 60,
    decoration: BoxDecoration(
      color: Colors.blue,
      boxShadow: [
        BoxShadow(
          blurRadius: 4,
          offset: const Offset(2, 2),
          color: Colors.black26,
        )
      ],
    ),
    child: const Center(child: Text("样式1", style: TextStyle(color: Colors.white))),
  ),
)

// 样式2箭头容器
ClipPath(
  clipper: ArrowClipPath(isStyleTwo: true),
  child: Container(
    width: 120,
    height: 60,
    color: Colors.green,
    child: const Center(child: Text("样式2", style: TextStyle(color: Colors.white))),
  ),
)

注意事项

你可以根据实际需求修改Path中的坐标比例,调整箭头的大小、箭头角度、缺口宽度等细节,直到匹配你需要的样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:11:06