You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

求Flutter解析嵌套JSON并实现ListView展示的示例代码

我懂你遇到的痛点啦——普通的Flutter JSON解析示例大多是单层级结构,碰到这种外层包了news数组的嵌套JSON就抓瞎了。下面给你一个完整的可运行示例,从模型定义、网络请求到ListView展示一步到位,完美适配你说的JSON结构~

完整Flutter嵌套JSON解析+ListView展示示例

第一步:定义对应的数据模型

首先得根据你的JSON结构({"news": [...]})创建两个模型类:一个外层的NewsResponse用来包裹整个响应,另一个NewsItem用来表示数组里的单条新闻数据。你可以根据实际返回的字段调整属性,这里我假设每条新闻有idtitlecontent这几个常见字段:

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

火山引擎 最新活动