Flutter加载本地JSON文件返回null报错求助
解决Flutter中FutureBuilder调用
[]方法时的null错误 嗨,刚看了你的代码,这个问题很典型——FutureBuilder的builder回调会被多次触发,第一次触发时异步请求还没完成,snapshot.data是null,这时候你直接调用json.decode(snapshot.data.toString()),相当于解码字符串"null",结果mydata还是null,后续访问mydata[index]自然就会抛出"The method '[]' was called on null."的错误。
问题根源拆解
当使用FutureBuilder时,它会经历几个关键状态:
- 初始加载状态:
snapshot.connectionState为ConnectionState.waiting,此时snapshot.data为null - 请求完成状态:
snapshot.connectionState变为ConnectionState.done,请求成功时snapshot.data才有有效数据 - 请求错误状态:如果加载失败,
snapshot.hasError会变为true
你当前的代码没有处理这些状态,直接跳过加载过程去解析数据,自然会遇到null的问题。
修复方案
我们需要在builder里先判断snapshot的状态,分情况处理:
- 请求加载中时,显示加载指示器
- 请求出错时,显示错误提示
- 请求成功且有数据时,再安全解析JSON并构建列表
下面是修改后的完整代码,关键修改处我用注释标出来了:
import 'package:flutter/material.dart'; import 'dart:convert'; void main() { runApp(MaterialApp( home: Home(), theme: ThemeData( primarySwatch: Colors.indigo, ), )); } class Home extends StatefulWidget { @override HomeState createState() => HomeState(); } class HomeState extends State<Home> { List data; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Some App"), ), body: Container( child: Center( child: FutureBuilder( future: DefaultAssetBundle.of(context).loadString('assets/data.json'), builder: (context, snapshot) { // 1. 处理加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 2. 处理错误状态 if (snapshot.hasError) { return Text('加载出错:${snapshot.error}'); } // 3. 确保数据不为null后再解析 if (snapshot.data == null) { return const Text('没有数据'); } // 现在可以安全解析JSON了 var mydata = json.decode(snapshot.data.toString()); print(mydata); return ListView.builder( itemBuilder: (BuildContext context, int index) { return Card( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ Text("Name " + mydata[index]['Name']), // 注意:如果Age是数字类型,要转成字符串再拼接 Text("Age " + mydata[index]['Age'].toString()), Text("Gender " + mydata[index]['Gender']), ], ), ); }, itemCount: mydata.length, ); }, ), ), ), ); } }
额外小提示
- 如果你的
data.json里的Age字段是数字类型,一定要转成字符串再和"Age "拼接,否则会触发类型错误(我已经在代码里加了注释提醒) - 用
const修饰不需要变化的Widget(比如静态文本、加载指示器),能小幅提升页面性能 - 可以把Future请求移到
initState方法中执行,避免每次页面build都重复发起请求(对于本地JSON文件影响不大,但养成好习惯很重要)
内容的提问来源于stack exchange,提问作者Sachihiro
相关产品推荐
相关产品推荐

