Flutter中如何在CustomPaint上方叠加Container组件
Flutter:CustomPaint上方叠加Container不显示的解决方法
问题分析
你遇到的问题是Stack中黑色Container无法显示在CustomPaint绘制的渐变图形上方,核心原因是外层SizedBox的高度限制导致Container被完全裁剪:
- 包裹Stack的SizedBox高度设为300
- Container设置了
top:250,自身高度300,意味着它的布局范围是从垂直方向250到550的位置,远超出了SizedBox的300高度上限,超出部分被完全裁剪,所以看不到任何痕迹。
另外,CustomPaint固定设置了size为250高度,没有占满Stack的全部空间,布局逻辑不够灵活。
预期效果:黑色Container叠加在渐变图形的底部区域,部分覆盖渐变图形
实际效果:黑色Container完全不可见
修复方案
方案1:调整外层容器高度,容纳所有元素
把包裹Stack的SizedBox高度从300改成足够容纳CustomPaint(250)和Container的高度(比如550),或者直接去掉固定高度,让Column自动适配:
SizedBox( // 改成足够容纳两个元素的高度,或者直接删除height属性 height: 550, child: Stack( children: [ // ... 原有代码 ], ), )
方案2:调整Container的位置和高度,适配现有空间
如果不想改外层高度,可以把Container的top值调小,同时降低自身高度,确保整体在SizedBox的300高度范围内:
Positioned( // 调整top值,比如设为200 top: 200, left: 10, right: 10, // 调整高度为100,确保200+100=300不超出SizedBox child: Container( height: 100, margin: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(10), ), ), )
方案3:优化CustomPaint的布局,让它自动占满Stack
建议给CustomPaint添加fit: BoxFit.fill,并去掉固定的size,让它自动适配Stack的大小,布局更灵活:
CustomPaint( painter: RPSCustomPainter(), fit: BoxFit.fill, // 新增这一行 // 删除固定的size属性 child: const Center( child: Text( "Démultiplier les liens et \ncoopérations de proximité", style: TextStyle( fontSize: 28, color: Colors.white, fontWeight: FontWeight.normal, ), textAlign: TextAlign.center, ), ), )
完整修复后的代码示例
class SectionOne extends StatelessWidget { const SectionOne({Key? key}) : super(key: key); Widget build(BuildContext context) { return Container( height: 800, child: Column( children: [ SizedBox( height: 550, // 调整高度容纳所有元素 child: Stack( children: [ CustomPaint( painter: RPSCustomPainter(), fit: BoxFit.fill, // 让CustomPaint占满Stack child: const Center( child: Text( "Démultiplier les liens et \ncoopérations de proximité", style: TextStyle( fontSize: 28, color: Colors.white, fontWeight: FontWeight.normal, ), textAlign: TextAlign.center, ), ), ), Positioned( top: 250, left: 10, right: 10, child: Container( height: 300, margin: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(10), ), ), ), ], ), ), OutlinedButtonWidget( text: "Voir les réseaux", style: OutlinedButtonWidgetStyle.filledOrange, onTap: () => Navigator.pop(context), ), ], ), ); } } // RPSCustomPainter 代码保持不变 class RPSCustomPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { Path path_0 = Path(); path_0.moveTo(0, 0); path_0.lineTo(size.width, 0); path_0.lineTo(size.width, size.height * 0.9758115); path_0.lineTo(size.width * 0.8525253, size.height * 0.9931386); path_0.cubicTo( size.width * 0.7427573, size.height * 1.006035, size.width * 0.6299280, size.height * 0.9955675, size.width * 0.5289173, size.height * 0.9631146); path_0.cubicTo( size.width * 0.4073333, size.height * 0.9240518, size.width * 0.2691413, size.height * 0.9177153, size.width * 0.1411925, size.height * 0.9453346); path_0.lineTo(0, size.height * 0.9758115); path_0.lineTo(0, 0); path_0.close(); Paint paint_0_fill = Paint()..style = PaintingStyle.fill; paint_0_fill.shader = LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ Color(0xff1F96C7).withOpacity(1), Color(0xff32B3AE).withOpacity(1), ], ).createShader(Rect.fromLTWH(0, 0, size.width, size.height)); canvas.drawPath(path_0, paint_0_fill); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } }
内容的提问来源于stack exchange,提问作者MICHEL Baptiste
相关产品推荐
相关产品推荐

