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

Flutter技术求助:如何在半透明矩形内实现透明圆形

实现半透明矩形内的透明圆形Widget

嘿,作为Flutter新手碰到这种自定义UI需求确实容易摸不着头脑,我直接给你一个可复用的Widget实现,再拆解下关键逻辑,你一看就懂啦!

完整实现代码

import 'package:flutter/material.dart';

class TransparentCircleInSemiTransparentRect extends StatelessWidget {
  // 可自定义的样式参数,方便按需调整
  final Color rectColor;
  final double rectOpacity;
  final double circleRadius;
  final EdgeInsetsGeometry padding;

  const TransparentCircleInSemiTransparentRect({
    super.key,
    this.rectColor = Colors.black,
    this.rectOpacity = 0.5,
    this.circleRadius = 40,
    this.padding = const EdgeInsets.all(20),
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: padding,
      child: CustomPaint(
        size: const Size(double.infinity, double.infinity),
        painter: _RectWithHolePainter(
          rectColor: rectColor.withOpacity(rectOpacity),
          circleRadius: circleRadius,
        ),
      ),
    );
  }
}

class _RectWithHolePainter extends CustomPainter {
  final Color rectColor;
  final double circleRadius;

  _RectWithHolePainter({
    required this.rectColor,
    required this.circleRadius,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // 1. 先绘制占满整个区域的半透明矩形
    final rectPaint = Paint()..color = rectColor;
    canvas.drawRect(Offset.zero & size, rectPaint);

    // 2. 用BlendMode.clear清除中间圆形区域,实现透明效果
    final circlePaint = Paint()..blendMode = BlendMode.clear;
    // 取矩形中心作为圆形的中心点
    final center = Offset(size.width / 2, size.height / 2);
    canvas.drawCircle(center, circleRadius, circlePaint);
  }

  @override
  bool shouldRepaint(covariant _RectWithHolePainter oldDelegate) {
    // 参数变化时触发重绘
    return oldDelegate.rectColor != rectColor ||
        oldDelegate.circleRadius != circleRadius;
  }
}

// 用法示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      backgroundColor: Colors.lightBlueAccent, // 用背景色衬托效果
      body: Center(
        child: SizedBox(
          width: 300,
          height: 200,
          child: TransparentCircleInSemiTransparentRect(
            rectColor: Colors.grey,
            rectOpacity: 0.6,
            circleRadius: 50,
          ),
        ),
      ),
    ),
  ));
}

关键逻辑拆解

  • CustomPaint核心作用:这是Flutter实现自定义图形的核心组件,通过CustomPainter我们可以直接操作画布绘制任意形状。
  • BlendMode.clear的妙用:这个混合模式是实现"挖洞"的关键——它会清除画布上对应区域的像素,让下方的内容完全透出来,完美实现圆形透明的效果。
  • 可灵活配置:我把矩形颜色、透明度、圆形半径都做成了可配置参数,你可以根据自己的UI需求随时调整数值。

你可以直接把这段代码复制到项目里,或者参考示例中的用法调用这个Widget,就能快速得到你想要的效果啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:02:45