Flutter 3.7.2升3.19.4后ColorFiltered效果差异及兼容方案咨询
问题:Flutter 3.19.4中ColorFiltered渲染效果与3.7.2不一致
升级Flutter从3.7.2到3.19.4后,使用ColorFiltered结合BlendMode.srcOut的渲染效果出现差异,测试代码如下:
class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( body: Container( color: Colors.green, child: const TestColorFilteredPage(), ), ); } } class TestColorFilteredPage extends StatelessWidget { const TestColorFilteredPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return ColorFiltered( colorFilter: const ColorFilter.mode(Colors.yellow, BlendMode.srcOut), child: Stack( children: [ Positioned.fill( child: Container( color: Colors.transparent, )), Positioned( top: 100, left: 100, child: Container( color: Colors.black, height: 100, width: 100, ), ) ], ), ); } }
- 3.7.2版本效果:绿色背景上显示黄色方块
- 3.19.4版本效果:绿色背景上无预期的黄色方块
解决方案
Flutter 3.10+版本对透明图层的渲染逻辑做了优化,原代码中Positioned.fill的透明容器无法再作为混合模式的目标图层(dst),导致BlendMode.srcOut无法正确计算混合效果。只需将该容器的颜色改为不透明的同背景色即可恢复原有效果:
修改后的TestColorFilteredPage代码:
class TestColorFilteredPage extends StatelessWidget { const TestColorFilteredPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return ColorFiltered( colorFilter: const ColorFilter.mode(Colors.yellow, BlendMode.srcOut), child: Stack( children: [ // 将透明容器替换为与外层一致的绿色背景 Positioned.fill(child: Container(color: Colors.green)), Positioned( top: 100, left: 100, child: Container( color: Colors.black, height: 100, width: 100, ), ) ], ), ); } }
原理:BlendMode.srcOut的计算逻辑为dst * (1 - src.a),必须存在不透明的目标图层(dst),才能让源图层(黑色方块)的区域反色显示为黄色。替换透明容器为不透明背景后,混合逻辑即可正常触发,与3.7.2版本效果一致。
内容的提问来源于stack exchange,提问作者qinglie
相关产品推荐
相关产品推荐

