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

Flutter 使用CustomPaint绘制半圆底部出现多余空白如何解决

你遇到的问题截图:
问题截图


问题原因

你当前绘制半圆时将圆心设置在了整个画布的中心点,绘制出的上半圆仅占画布的上半区域,画布下半部分自然就会出现空白区域。同时因为外层Flexible设置了FlexFit.tight,CustomPaint的自定义size参数被父布局约束覆盖,所以你调整size看不到效果。

CustomPaint的size参数作用

CustomPaint的size是优先级最低的尺寸配置:

  • 当CustomPaint没有子节点,且父组件没有设置强制布局约束时,它会用你传入的size作为自身的绘制区域尺寸
  • 如果父组件有严格的布局约束(比如FlexFit.tight模式、SizedBox强制尺寸),或者CustomPaint设置了child子节点,size参数就会直接失效,CustomPaint会使用父约束/子节点的尺寸作为绘制区域大小

解决方案

只需要调整绘制半圆的圆心位置即可,不需要额外裁剪:

  1. 把半圆的圆心从画布中心点改到画布底部的中点,这样绘制的上半圆刚好撑满整个画布,不会留下底部空白
  2. 修正你当前代码里的语法错误(shouldRepaint方法放在了paint方法内、错误给自定义方法加override)
  3. 不需要额外的Transform.rotate旋转组件

自定义Painter代码

import 'dart:math';
import 'package:flutter/material.dart';

class MyPainter extends CustomPainter {
  final Paint redCircle = Paint()
    ..color = Colors.red
    ..style = PaintingStyle.stroke
    ..strokeWidth = 50; // 可自行调整描边宽度

  @override
  void paint(Canvas canvas, Size size) {
    // 圆心设置为画布底部中点
    final center = Offset(size.width / 2, size.height);
    // 半径等于画布高度,刚好让半圆顶部对齐画布顶部
    final radius = size.height;

    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius - 25), // 可自行调整偏移值
      -pi / 2, // 等价于你写的doubleToAngle(-90)
      pi, // 等价于doubleToAngle(180)
      false,
      redCircle,
    );
  }

  @override
  bool shouldRepaint(MyPainter oldDelegate) {
    // 按你自己的业务逻辑调整是否需要重绘
    return false;
  }

  double doubleToAngle(double angle) => angle * pi / 180.0;
}

嵌入布局代码

Flexible(
  flex: 2,
  fit: FlexFit.tight,
  child: CustomPaint(
    size: const Size(300, 150),
    key: backgroundKey,
    painter: MyPainter(),
  ),
)

如果后续还有超出绘制区域的内容需要裁剪,可以在CustomPaint外层套ClipRect组件强制裁剪超出布局边界的内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:09:02