Flutter中如何让CustomPaint覆盖Camera Preview?
解决CustomPaint显示在CameraPreview下方的问题
我明白你遇到的困扰了——你想让自定义绘制的内容显示在相机预览的上方,但现在它被相机预览给挡住了。这是因为你把CameraPreview作为CustomPaint的child,而CustomPaint的painter属性是在child的底层进行绘制的,所以相机预览层会覆盖掉你画的红线。
这里有两种简单的解决办法:
方法1:使用CustomPaint的foregroundPainter属性
CustomPaint提供了foregroundPainter属性,它会在child的上层进行绘制,刚好符合你的需求。只需要把原来的painter替换成foregroundPainter就行:
class _CameraPreviewState extends State<CameraPreview> { [...] Widget build(BuildContext context) { double height = MediaQuery.of(context).size.height; return YidKitTheme( child: Center( child: _isReady ? Container( height: height / 2, child: CustomPaint( // 把painter换成foregroundPainter foregroundPainter: GuidelinePainter(), child: AspectRatio( aspectRatio: controller.value.aspectRatio, child: CameraPreview(controller) ), ) ) : CircularProgressIndicator() ) ); } } class GuidelinePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { Paint paint = Paint() ..strokeWidth = 3.0 ..color = Colors.red ..style = PaintingStyle.stroke; var path = Path()..lineTo(50.0, 50.0); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) => true; }
方法2:用Stack组件叠加层级
如果后续你需要更灵活地控制各个组件的位置和层级,用Stack是更好的选择。把CameraPreview放在Stack的底层,CustomPaint放在上层:
class _CameraPreviewState extends State<CameraPreview> { [...] Widget build(BuildContext context) { double height = MediaQuery.of(context).size.height; return YidKitTheme( child: Center( child: _isReady ? Container( height: height / 2, child: Stack( children: [ // 底层放相机预览 AspectRatio( aspectRatio: controller.value.aspectRatio, child: CameraPreview(controller) ), // 上层放自定义绘制 CustomPaint( painter: GuidelinePainter(), // 让CustomPaint占满整个父容器的大小 size: Size.infinite, ) ], ) ) : CircularProgressIndicator() ) ); } } // GuidelinePainter代码保持不变 class GuidelinePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { Paint paint = Paint() ..strokeWidth = 3.0 ..color = Colors.red ..style = PaintingStyle.stroke; var path = Path()..lineTo(50.0, 50.0); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) => true; }
两种方法都能解决你的问题,你可以根据自己的需求选择。如果只是简单的上层绘制,方法1更简洁;如果需要复杂的布局,方法2更灵活。
内容的提问来源于stack exchange,提问作者MrWhetherMan
相关产品推荐
相关产品推荐

