You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter JSON解析报错及点击浮动按钮带加载动画刷新功能实现问题

问题解决方案

错误根因

  1. JSON解析报错是因为返回结果是数组类型,原有代码直接将数组转为单个Map对象传入Album.fromJson导致类型不匹配,同时Album.fromJson中取了不存在的name字段,实际返回字段为title
  2. 点击刷新不显示加载圈的问题,原有逻辑是对的,只要修正数据类型后,setState更新future变量即可触发FutureBuilder重新进入加载状态

修正后完整空安全代码

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

// 替换为你的实际接口地址
const String myLocksEp = 'https://xxx.com/xxx';

Future<List<Album>> fetchAlbum() async {
  print("Fetching json....");
  final response = await http.get(
    Uri.parse(myLocksEp),
  );

  if (response.statusCode == 200) {
    print(response.body);
    // 解析数组:先转成List<dynamic>,再逐个转为Album对象
    List<dynamic> jsonList = jsonDecode(response.body);
    return jsonList.map((jsonItem) => Album.fromJson(jsonItem)).toList();
  } else {
    throw Exception('Failed to load album');
  }
}

class Album {
  final int id;
  final String title;
  final int userId;

  Album({required this.id, required this.title, required this.userId});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['id'],
      title: json['title'], // 修正字段取值,和返回JSON对齐
      userId: json['userId'],
    );
  }
}

void main() {
  runApp(const MyLocks());
}

// Dart类名规范使用大驼峰
class MyLocks extends StatefulWidget {
  const MyLocks({super.key});

  @override
  _MyAppState createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyLocks> {
  // 调整为List<Album>类型
  late Future<List<Album>> _futureAlbum;

  @override
  void initState() {
    super.initState();
    _futureAlbum = fetchAlbum();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.all(8.0),
          // 调整FutureBuilder泛型为List<Album>
          child: FutureBuilder<List<Album>>(
            future: _futureAlbum,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasData) {
                  // 加载完成返回ListView渲染列表
                  return ListView.builder(
                    itemCount: snapshot.data!.length,
                    itemBuilder: (context, index) {
                      Album item = snapshot.data![index];
                      return ListTile(
                        title: Text(item.title),
                        subtitle: Text("用户ID:${item.userId},ID:${item.id}"),
                      );
                    },
                  );
                } else if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                }
              }
              // 加载中自动显示进度圈
              return const CircularProgressIndicator();
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.refresh_outlined, color: Colors.black),
          backgroundColor: Colors.grey[200],
          onPressed: () {
            setState(() {
              _futureAlbum = fetchAlbum();
            });
          },
        ),
      ),
    );
  }
}

核心修改说明

  • 调整数据请求返回类型为Future<List<Album>>,匹配接口返回的JSON数组结构,解析时遍历数组完成对象转换
  • 修正Album.fromJson的字段取值错误,避免空值异常
  • 加载完成后渲染ListView组件,将接口返回的所有数据展示为列表项
  • 点击刷新按钮调用setState更新_futureAlbum变量,FutureBuilder检测到future变更后自动进入加载状态,展示CircularProgressIndicator,无需额外处理加载逻辑

内容的提问来源于stack exchange,提问作者Robbal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 14:24:03