新增一个chat_popup 来显示聊天窗口
This commit is contained in:
80
lib/widgets/_hole_overlay.dart
Normal file
80
lib/widgets/_hole_overlay.dart
Normal file
@@ -0,0 +1,80 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
|
||||
/// 遮罩层,icon 区域挖洞可交互
|
||||
class HoleOverlay extends StatelessWidget {
|
||||
final Offset iconPosition;
|
||||
final double iconSize;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const HoleOverlay({
|
||||
super.key,
|
||||
required this.iconPosition,
|
||||
required this.iconSize,
|
||||
this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Listener(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onPointerDown: (PointerDownEvent event) {
|
||||
final RenderBox box = context.findRenderObject() as RenderBox;
|
||||
final Offset local = box.globalToLocal(event.position);
|
||||
final iconRect = Rect.fromLTWH(
|
||||
iconPosition.dx,
|
||||
iconPosition.dy,
|
||||
iconSize,
|
||||
iconSize,
|
||||
);
|
||||
if (!iconRect.contains(local)) {
|
||||
// 遮罩区域,拦截并关闭弹窗
|
||||
if (onTap != null) {
|
||||
onTap!();
|
||||
}
|
||||
}
|
||||
// 如果点在icon区域,什么都不做,事件会传递到下层
|
||||
},
|
||||
child: CustomPaint(
|
||||
size: Size.infinite,
|
||||
painter: _HolePainter(
|
||||
iconPosition: iconPosition,
|
||||
iconSize: iconSize,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HolePainter extends CustomPainter {
|
||||
final Offset iconPosition;
|
||||
final double iconSize;
|
||||
|
||||
_HolePainter({required this.iconPosition, required this.iconSize});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()
|
||||
..color = Colors.white.withOpacity(0.0)
|
||||
..blendMode = BlendMode.srcOver;
|
||||
|
||||
// 画全屏遮罩
|
||||
canvas.drawRect(Offset.zero & size, paint);
|
||||
|
||||
// 挖洞
|
||||
final holeRect = Rect.fromLTWH(
|
||||
iconPosition.dx,
|
||||
iconPosition.dy,
|
||||
iconSize,
|
||||
iconSize,
|
||||
);
|
||||
final holePath = Path()..addOval(holeRect);
|
||||
paint.blendMode = BlendMode.clear;
|
||||
canvas.drawPath(holePath, paint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant _HolePainter oldDelegate) {
|
||||
return iconPosition != oldDelegate.iconPosition || iconSize != oldDelegate.iconSize;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user