如何用Flutter实现此类半钻孔边框效果?
Flutter中心镂空带阴影组件实现方案
直接上可运行的实现代码,核心用CustomPainter结合混合模式实现镂空,同时正确处理阴影层级:
import 'package:flutter/material.dart'; class HollowShadowPainter extends CustomPainter { final Color shadowColor; final double shadowBlurRadius; final Offset shadowOffset; final Color fillColor; final double hollowRadius; // 中心镂空区域的圆角半径 final double hollowPadding; // 镂空区域到外层的间距 HollowShadowPainter({ required this.shadowColor, this.shadowBlurRadius = 8.0, this.shadowOffset = const Offset(0, 2), required this.fillColor, this.hollowRadius = 8.0, this.hollowPadding = 20.0, }); @override void paint(Canvas canvas, Size size) { // 1. 定义外层圆角矩形路径 final outerRRect = RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), const Radius.circular(12), ); // 2. 绘制阴影:先画阴影,确保在最底层 canvas.drawShadow( outerRRect, shadowColor, shadowBlurRadius, true, // 设为true让阴影形状更自然 ); // 3. 绘制外层填充色 final fillPaint = Paint()..color = fillColor; canvas.drawRRect(outerRRect, fillPaint); // 4. 定义中心镂空区域的路径 final hollowRect = Rect.fromLTWH( hollowPadding, hollowPadding, size.width - hollowPadding * 2, size.height - hollowPadding * 2, ); final hollowRRect = RRect.fromRectAndRadius( hollowRect, Radius.circular(hollowRadius), ); // 5. 用混合模式挖空中心区域 final hollowPaint = Paint() ..blendMode = BlendMode.clear; // 清除对应区域的像素实现镂空 canvas.drawRRect(hollowRRect, hollowPaint); } @override bool shouldRepaint(covariant HollowShadowPainter oldDelegate) { return oldDelegate.shadowColor != shadowColor || oldDelegate.shadowBlurRadius != shadowBlurRadius || oldDelegate.shadowOffset != shadowOffset || oldDelegate.fillColor != fillColor || oldDelegate.hollowRadius != hollowRadius || oldDelegate.hollowPadding != hollowPadding; } } // 使用示例 class HollowShadowWidget extends StatelessWidget { const HollowShadowWidget({super.key}); @override Widget build(BuildContext context) { return SizedBox( width: 200, height: 200, child: CustomPaint( painter: HollowShadowPainter( shadowColor: Colors.grey.withOpacity(0.5), fillColor: Colors.white, hollowPadding: 30, ), // Android上若镂空异常,添加此参数关闭硬件加速 isComplex: true, ), ); } }
关键细节说明
- 阴影层级:先调用
drawShadow绘制阴影,再绘制外层填充,确保阴影不会被填充色覆盖 - 镂空实现:用
BlendMode.clear模式绘制中心区域,直接清除画布对应位置的像素,是真正的镂空(不是用背景色遮挡) - Android兼容性:如果Android上镂空区域显示异常,给
CustomPaint加上isComplex: true,强制关闭硬件加速即可解决混合模式渲染问题
如果需要调整镂空形状(比如圆形、不规则形),只需要修改第4步的hollowRRect为对应的路径即可。
内容的提问来源于stack exchange,提问作者Kallen
相关产品推荐
相关产品推荐

