Flutter中CircleAvatar加载JSON解析图片URI返回null问题排查
问题排查与修复方案
核心问题分析
- 异步加载未完成就访问数据:
loadJsonAsset是异步方法,你在build里直接调用它,但不会等待执行完毕。此时jsonData还是初始的null,直接访问jsonData[0]['assetURI']必然触发空指针异常。 - 无状态组件无法更新UI:用
StatelessWidget的话,就算后续jsonData加载完成,组件也不会自动刷新UI展示新数据。 - 重复调用异步方法:每次
build执行都会调用loadJsonAsset,导致重复读取JSON文件,浪费资源。
修复后的代码
class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { // 用Future存储JSON加载结果,避免重复加载 late Future<List<dynamic>> _jsonFuture; Future<List<dynamic>> loadJsonAsset() async { final String jsonString = await rootBundle.loadString('assets/json/asset.json'); return jsonDecode(jsonString); } @override void initState() { super.initState(); // 组件初始化时仅加载一次JSON _jsonFuture = loadJsonAsset(); } @override Widget build(BuildContext context) { return Scaffold( body: FutureBuilder<List<dynamic>>( future: _jsonFuture, builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 加载出错状态 if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } // 加载成功,获取数据 final jsonData = snapshot.data!; return ListView.builder( itemCount: jsonData.length, // 用JSON数据长度作为列表项数量 itemBuilder: (context, index) { return CircleAvatar( backgroundImage: AssetImage(jsonData[index]['assetURI']), maxRadius: 30, ); }, ); }, ), ); } }
关键改动说明
- 改用
StatefulWidget:允许组件管理异步状态,加载完成后触发UI刷新。 - 使用
FutureBuilder:专门处理异步任务的Widget,能根据异步任务的不同状态(加载中、成功、失败)渲染对应UI。 - 把JSON加载逻辑放在
initState:确保组件初始化时只加载一次JSON,避免重复调用。 - 基于JSON数据长度设置
itemCount:不再依赖硬编码数组长度,更灵活。 - 增加状态处理:添加加载中和加载失败的提示,提升用户体验。
内容的提问来源于stack exchange,提问作者No name
相关产品推荐
相关产品推荐

