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

Flutter中如何使用Paint类实现底部虚线其余边实线的混合描边

实现方案

核心思路是将边框路径拆分为两部分分开绘制:

  • 第一部分为顶部、左右侧边、四个圆角,用实线绘制
  • 第二部分为底部直边,单独处理为虚线绘制
    Flutter 原生 Paint 未提供虚线参数,我们通过路径度量(PathMetric)实现虚线效果。

修改后的完整 CustomPainter 代码

import 'package:flutter/material.dart';

// 虚线转换辅助方法
Path dashPath(Path source, {required double dashWidth, required double dashSpace}) {
  final Path dashedPath = Path();
  for (final PathMetric metric in source.computeMetrics()) {
    double distance = 0;
    bool draw = true;
    while (distance < metric.length) {
      final double len = draw ? dashWidth : dashSpace;
      if (draw) {
        dashedPath.addPath(metric.extractPath(distance, distance + len), Offset.zero);
      }
      distance += len;
      draw = !draw;
    }
  }
  return dashedPath;
}

class UpperCustomPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    double radius = 44.0, w = size.width, h = size.height;

    // 1. 绘制实线部分(不含底部直边)
    Paint solidPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10.0
      ..strokeJoin = StrokeJoin.miter
      ..color = Colors.blue; // 替换为你需要的容器颜色

    Path solidPath = Path();
    solidPath.moveTo(radius, 0);
    solidPath.lineTo(w - radius, 0);
    solidPath.arcToPoint(Offset(w, radius), radius: Radius.circular(radius));
    solidPath.lineTo(w, h - radius);
    solidPath.arcToPoint(Offset(w - radius, h), radius: Radius.circular(radius), clockwise: false);
    // 跳过底部直边,直接移动到左下角圆角起点
    solidPath.moveTo(radius, h);
    solidPath.arcToPoint(Offset(0, h - radius), radius: Radius.circular(radius), clockwise: false);
    solidPath.lineTo(0, radius);
    solidPath.arcToPoint(Offset(radius, 0), radius: Radius.circular(radius));
    canvas.drawPath(solidPath, solidPaint);

    // 2. 绘制底部虚线
    Paint dashPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10.0
      ..color = Colors.blue;

    Path bottomLine = Path();
    bottomLine.moveTo(w - radius, h);
    bottomLine.lineTo(radius, h);
    // 可自行调整 dashWidth(虚线段长度)和 dashSpace(间隔长度)匹配设计需求
    Path dashedBottom = dashPath(bottomLine, dashWidth: 12, dashSpace: 8);
    canvas.drawPath(dashedBottom, dashPaint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

如果需要调整虚线的疏密,修改dashPath方法传入的dashWidth和dashSpace参数即可,UpperCustomClipper部分无需修改可直接沿用原有代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 13:15:07