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

Flutter请求API数据时无法显示CircularProgressIndicator问题求助

问题原因与解决方案

你的加载指示器不显示,核心原因是网络请求完成速度过快,fetchdata中两次setState的间隔太短,UI线程还没来得及渲染加载状态,就已经切换到了数据展示状态。另外代码还存在maplist未初始化的潜在空指针问题。

修复方案1:优化手动状态管理

先初始化maplist为空列表,同时可给网络请求加短暂延迟(仅用于测试加载效果,生产环境删除),确保加载状态能被渲染:

class _HomeScreenState extends State<HomeScreen> {
  bool isloading = false;
  var maplist = []; // 初始化空列表,避免空指针

  Future<void> fetchdata() async {
    setState(() {
      isloading = true;
    });

    // 测试用:添加1秒延迟,让加载指示器有时间显示(生产环境删除此行)
    await Future.delayed(const Duration(seconds: 1));

    var resp = await http.get(Uri.parse("https://jsonplaceholder.typicode.com/posts"));
    maplist = json.decode(resp.body);
    
    setState(() {
      isloading = false;
    });
  }

  @override
  void initState() {
    super.initState();
    fetchdata();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: isloading 
            ? const Center(child: CircularProgressIndicator()) 
            : ListView.builder(
                itemCount: maplist.length,
                itemBuilder: (context, index) {
                  return Container(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(maplist[index]['title']),
                  );
                },
              ),
      ),
    );
  }
}

修复方案2:使用FutureBuilder(推荐)

Flutter官方推荐用FutureBuilder管理异步任务状态,无需手动维护isloading变量,逻辑更简洁可靠:

class _HomeScreenState extends State<HomeScreen> {
  late Future<List<dynamic>> futurePosts;

  Future<List<dynamic>> fetchdata() async {
    var resp = await http.get(Uri.parse("https://jsonplaceholder.typicode.com/posts"));
    return json.decode(resp.body);
  }

  @override
  void initState() {
    super.initState();
    futurePosts = fetchdata();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: FutureBuilder<List<dynamic>>(
          future: futurePosts,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Center(child: CircularProgressIndicator());
            } else if (snapshot.hasError) {
              return Center(child: Text('加载失败: ${snapshot.error}'));
            } else {
              return ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  return Container(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(snapshot.data![index]['title']),
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

关键说明

  • 方案1中初始化maplist为空列表,避免了数据未加载完成时调用maplist.length引发的空指针异常
  • 方案2的FutureBuilder会自动根据异步任务的状态(等待/成功/失败)渲染对应UI,无需手动管理加载状态,代码更健壮
  • 实际生产环境中,网络请求速度取决于用户的网络环境,若网络较慢,方案1也能正常显示加载指示器;添加延迟只是为了在本地调试时能看到加载效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:10:57