求Flutter解析嵌套JSON并实现ListView展示的示例代码
我懂你遇到的痛点啦——普通的Flutter JSON解析示例大多是单层级结构,碰到这种外层包了news数组的嵌套JSON就抓瞎了。下面给你一个完整的可运行示例,从模型定义、网络请求到ListView展示一步到位,完美适配你说的JSON结构~
完整Flutter嵌套JSON解析+ListView展示示例
第一步:定义对应的数据模型
首先得根据你的JSON结构({"news": [...]})创建两个模型类:一个外层的NewsResponse用来包裹整个响应,另一个NewsItem用来表示数组里的单条新闻数据。你可以根据实际返回的字段调整属性,这里我假设每条新闻有id、title、content这几个常见字段:
class NewsResponse { final List<NewsItem> news; NewsResponse({required this.news}); // 把JSON映射成模型实例 factory NewsResponse.fromJson(Map<String, dynamic> json) { // 先把news数组转成List,再逐个映射成NewsItem var newsList = json['news'] as List; List<NewsItem> newsItems = newsList.map((item) => NewsItem.fromJson(item)).toList(); return NewsResponse(news: newsItems); } } class NewsItem { final int id; final String title; final String content; NewsItem({required this.id, required this.title, required this.content}); factory NewsItem.fromJson(Map<String, dynamic> json) { return NewsItem( id: json['id'], title: json['title'], content: json['content'], // 这里根据实际返回的字段添加更多属性,比如发布时间、封面图等 ); } }
第二步:实现网络请求与JSON解析
接下来写一个异步方法,负责发起网络请求并把返回的JSON解析成我们的模型:
import 'dart:convert'; import 'package:http/http.dart' as http; Future<NewsResponse> fetchNews() async { final response = await http.get(Uri.parse('http://api.radiomedia.com.au/api-access/news')); if (response.statusCode == 200) { // 解析成功,返回模型实例 return NewsResponse.fromJson(json.decode(response.body)); } else { // 请求失败抛出异常 throw Exception('加载新闻失败,请稍后重试'); } }
第三步:用ListView展示解析后的数据
最后用FutureBuilder处理异步请求状态,把解析好的新闻列表渲染到ListView里:
import 'package:flutter/material.dart'; class NewsListScreen extends StatelessWidget { const NewsListScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('新闻列表')), body: FutureBuilder<NewsResponse>( future: fetchNews(), builder: (context, snapshot) { // 数据加载完成 if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data!.news.length, itemBuilder: (context, index) { NewsItem news = snapshot.data!.news[index]; return ListTile( leading: CircleAvatar(child: Text(news.id.toString())), title: Text(news.title, style: const TextStyle(fontWeight: FontWeight.bold)), subtitle: Text(news.content, maxLines: 2, overflow: TextOverflow.ellipsis), onTap: () { // 这里可以添加点击新闻项的操作,比如跳转到详情页 }, ); }, ); } // 加载出错 else if (snapshot.hasError) { return Center(child: Text('出错了:${snapshot.error}')); } // 加载中状态 return const Center(child: CircularProgressIndicator()); }, ), ); } }
额外注意事项
- 记得在
pubspec.yaml里添加http依赖:dependencies: flutter: sdk: flutter http: ^1.1.0 # 可以换成最新版本 - 如果实际返回的JSON字段和你定义的模型字段不匹配,一定要对应调整
fromJson里的映射关系,比如如果字段是news_title,就要写成title: json['news_title']。 - 可以额外添加网络状态判断或者错误重试逻辑,提升用户体验。
内容的提问来源于stack exchange,提问作者RussellHarrower




