Flutter实现ListView.builder时Note.fromJson报预期String得Null错误如何解决
问题原因
- JSON字段映射错误:你调用的
https://jsonplaceholder.typicode.com/posts接口返回的单条数据内容字段为body,而非text,所以json['text']取到Null,赋值给非空String类型的text属性触发类型不匹配报错。 - 网络请求逻辑不规范:你将请求方法放在
build函数中,每次组件重绘都会重复发起请求,且请求完成后更新数组没有调用setState,不会触发界面刷新。
修复方案
步骤1:修正Note类的字段映射
给字段取值添加默认空兜底,同时匹配接口实际返回的字段:
class Note { late String title; late String text; Note(this.title, this.text); Note.fromJson(Map<String, dynamic> json) { // 匹配接口返回的body字段,取不到时给默认值避免空异常 title = json['title'] ?? '无标题'; text = json['body'] ?? '无内容'; } }
如果你需要兼容字段可能为空的场景,也可以将属性声明为可空类型,使用时判空即可:
class Note { String? title; String? text; Note(this.title, this.text); Note.fromJson(Map<String, dynamic> json) { title = json['title']; text = json['body']; } } // 界面使用时添加判空逻辑 Text(_notes[index].title ?? '无标题') Text(_notes[index].text ?? '无内容')
步骤2:修正网络请求调用逻辑
将请求放到initState中仅执行一次,请求完成后调用setState更新界面:
class _MyAppState extends State<MyApp> { List<Note> _notes = []; // 添加加载状态用于展示加载动画 bool _isLoading = true; @override void initState() { super.initState(); // 页面初始化时发起请求 fetchNotes(); } Future<void> fetchNotes() async { var response = await http.get(Uri.parse("https://jsonplaceholder.typicode.com/posts")); var notes = <Note>[]; if (response.statusCode == 200) { var notesJson = jsonDecode(response.body); for (var noteJson in notesJson) { notes.add(Note.fromJson(noteJson)); } } // 更新状态触发重绘 setState(() { _notes = notes; _isLoading = false; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("Listview with Json"), ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemBuilder: (context, index) { return Card( child: Padding( padding: const EdgeInsets.only( top: 32.0, bottom: 32.0, left: 16.0, right: 16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( _notes[index].title, style: TextStyle( fontSize: 22, fontWeight: FontWeight.bold), ), Text( _notes[index].text, style: TextStyle(color: Colors.grey.shade700), ) ], ), ), ); }, itemCount: _notes.length, ))); } }
内容的提问来源于stack exchange,提问作者Ali Punjabi
相关产品推荐
相关产品推荐

