InkWell搭配Ink使用时Image的errorBuilder未触发问题咨询
问题:Ink.image配合Image.asset时errorBuilder未触发
希望图片资源不存在时调用errorBuilder回调,但当Image与InkWell + Ink配合使用时,该回调并未被触发。
代码示例:
main() { runApp( MaterialApp( home: Scaffold( body: Center( child: InkWell( child: Ink.image( image: Image.asset( 'assets/does-not-exist.png', // 未被调用: errorBuilder: (context, error, stackTrace) { return Text('$error'); }, ).image, fit: BoxFit.cover, height: 400, ), onTap: () {}, ), ), ), ), ); }
原因分析
你这里是通过Image.asset(...).image提取了ImageProvider对象传给Ink.image,但errorBuilder是**Image组件独有的回调**,不是ImageProvider的属性。当ImageProvider加载失败时,Image组件本身根本没被渲染到界面上,自然不会触发它的errorBuilder。
解决方案
方案一:用Image作为Ink的子组件(推荐)
把Image组件直接放在Ink内部作为子元素,这样Image能正常渲染,errorBuilder也能在加载失败时触发,同时InkWell的水波纹效果依然有效。
修改后的代码:
main() { runApp( MaterialApp( home: Scaffold( body: Center( child: InkWell( onTap: () {}, child: Ink( height: 400, child: Image.asset( 'assets/does-not-exist.png', fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Text('$error'); }, ), ), ), ), ), ), ); }
方案二:提前校验图片是否存在
如果一定要用Ink.image的写法,可以先通过rootBundle校验资源是否存在,再动态渲染内容:
import 'package:flutter/services.dart'; main() { runApp( MaterialApp( home: Scaffold( body: Center( child: FutureBuilder<bool>( future: _checkImageExists('assets/does-not-exist.png'), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 图片存在则渲染Ink.image,否则显示错误提示 return InkWell( onTap: () {}, child: snapshot.data == true ? Ink.image( image: const AssetImage('assets/does-not-exist.png'), fit: BoxFit.cover, height: 400, ) : Ink( height: 400, child: const Text('图片加载失败'), ), ); }, ), ), ), ), ); } // 校验资源是否存在的工具方法 Future<bool> _checkImageExists(String path) async { try { await rootBundle.load(path); return true; } catch (_) { return false; } }
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

