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

求助:如何在Flutter中绘制自定义点赞与点踩路径

在Flutter中绘制自定义点赞/点踩路径

你可以通过Flutter的CustomPaint和CustomPainter组件直接绘制自定义的点赞、点踩图标,以下是具体实现方案:

1. 实现点赞图标绘制器

创建继承自CustomPainter的子类,通过Path构建点赞的形状路径:

class ThumbUpPainter extends CustomPainter {
  final Color color;
  final double strokeWidth;

  ThumbUpPainter({this.color = Colors.blue, this.strokeWidth = 2.0});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = color
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;

    final path = Path();
    // 绘制拇指外轮廓
    path.moveTo(size.width * 0.5, size.height * 0.1);
    path.quadraticBezierTo(size.width * 0.7, size.height * 0.2, size.width * 0.8, size.height * 0.4);
    path.lineTo(size.width * 0.7, size.height * 0.6);
    path.quadraticBezierTo(size.width * 0.5, size.height * 0.7, size.width * 0.3, size.height * 0.6);
    path.lineTo(size.width * 0.2, size.height * 0.4);
    path.quadraticBezierTo(size.width * 0.3, size.height * 0.2, size.width * 0.5, size.height * 0.1);
    // 绘制拇指内侧细节
    path.moveTo(size.width * 0.5, size.height * 0.15);
    path.quadraticBezierTo(size.width * 0.6, size.height * 0.25, size.width * 0.65, size.height * 0.4);
    path.lineTo(size.width * 0.55, size.height * 0.5);
    path.quadraticBezierTo(size.width * 0.5, size.height * 0.55, size.width * 0.4, size.height * 0.5);
    path.lineTo(size.width * 0.35, size.height * 0.35);
    path.quadraticBezierTo(size.width * 0.4, size.height * 0.2, size.width * 0.5, size.height * 0.15);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant ThumbUpPainter oldDelegate) {
    return oldDelegate.color != color || oldDelegate.strokeWidth != strokeWidth;
  }
}

2. 实现点踩图标绘制器

同理,调整路径坐标实现点踩形状:

class ThumbDownPainter extends CustomPainter {
  final Color color;
  final double strokeWidth;

  ThumbDownPainter({this.color = Colors.red, this.strokeWidth = 2.0});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = color
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;

    final path = Path();
    // 绘制拇指外轮廓
    path.moveTo(size.width * 0.5, size.height * 0.9);
    path.quadraticBezierTo(size.width * 0.7, size.height * 0.8, size.width * 0.8, size.height * 0.6);
    path.lineTo(size.width * 0.7, size.height * 0.4);
    path.quadraticBezierTo(size.width * 0.5, size.height * 0.3, size.width * 0.3, size.height * 0.4);
    path.lineTo(size.width * 0.2, size.height * 0.6);
    path.quadraticBezierTo(size.width * 0.3, size.height * 0.8, size.width * 0.5, size.height * 0.9);
    // 绘制拇指内侧细节
    path.moveTo(size.width * 0.5, size.height * 0.85);
    path.quadraticBezierTo(size.width * 0.6, size.height * 0.75, size.width * 0.65, size.height * 0.6);
    path.lineTo(size.width * 0.55, size.height * 0.5);
    path.quadraticBezierTo(size.width * 0.5, size.height * 0.45, size.width * 0.4, size.height * 0.5);
    path.lineTo(size.width * 0.35, size.height * 0.65);
    path.quadraticBezierTo(size.width * 0.4, size.height * 0.8, size.width * 0.5, size.height * 0.85);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant ThumbDownPainter oldDelegate) {
    return oldDelegate.color != color || oldDelegate.strokeWidth != strokeWidth;
  }
}

3. 在页面中使用绘制器

通过CustomPaint组件将绘制器渲染到页面:

class ThumbIconsPage extends StatelessWidget {
  const ThumbIconsPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('自定义点赞/点踩')),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CustomPaint(
              size: const Size(60, 80),
              painter: ThumbUpPainter(color: Colors.green, strokeWidth: 3.0),
            ),
            const SizedBox(width: 40),
            CustomPaint(
              size: const Size(60, 80),
              painter: ThumbDownPainter(color: Colors.red, strokeWidth: 3.0),
            ),
          ],
        ),
      ),
    );
  }
}

自定义调整技巧

  • 修改形状:调整Path中的坐标比例(比如size.width * 0.5),可以改变图标的粗细、弯曲度和整体比例。
  • 实心样式:将PaintingStyle.stroke改为PaintingStyle.fill,即可得到实心图标。
  • 交互效果:给CustomPaint包裹GestureDetector,配合状态管理(比如StatefulWidget),可以实现点击切换选中状态(比如变色、切换填充/描边)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:25:22