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
相关产品推荐
相关产品推荐

