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

Flutter中如何停止CircularProgressIndicator?解决无数据时持续加载问题

Great question! The issue here has two key parts: your current code doesn’t handle timeouts for the API call (so the indicator spins forever if the request hangs), and it doesn’t account for empty data returned from the server. Let’s fix both problems with these targeted adjustments:

Step 1: Add Timeout to the API Request

First, we’ll modify the fetchStudents function to timeout after a specified duration (e.g., 5 seconds). This ensures the future completes even if the server doesn’t respond, stopping the progress indicator and notifying the user of the issue.

Step 2: Handle All Edge Cases in FutureBuilder

Instead of only checking for the presence of data, we’ll cover all possible states:

  • Show the indicator only while the request is in progress
  • Display an error message if the request times out or fails
  • Show a clear "no data" message if the server returns an empty list
  • Render the list only when we have valid, non-empty data

Full Corrected Code

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

class Studentdata {
  final String studentName;

  Studentdata({required this.studentName});

  factory Studentdata.fromJson(Map<String, dynamic> json) {
    return Studentdata(
      studentName: json['studentName'] as String,
    );
  }
}

class MainListView extends StatefulWidget {
  @override
  MainListViewState createState() => MainListViewState();
}

class MainListViewState extends State<MainListView> {
  final String apiURL = 'http://====================/getStudentInfo.php';

  Future<List<Studentdata>> fetchStudents() async {
    try {
      // Add a 5-second timeout to the request
      var response = await http.get(Uri.parse(apiURL)).timeout(
            const Duration(seconds: 5),
            onTimeout: () {
              throw TimeoutException('Request took too long to complete');
            },
          );

      if (response.statusCode == 200) {
        final items = json.decode(response.body).cast<Map<String, dynamic>>();
        List<Studentdata> studentList = items.map<Studentdata>((json) {
          return Studentdata.fromJson(json);
        }).toList();
        return studentList;
      } else {
        throw Exception('Failed to load data from Server. Status code: ${response.statusCode}');
      }
    } on TimeoutException catch (e) {
      throw Exception('Timeout: ${e.message}');
    } catch (e) {
      throw Exception('Error fetching data: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Studentdata>>(
      future: fetchStudents(),
      builder: (context, snapshot) {
        // Show indicator while waiting for the future to complete
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }
        // Show error message if request failed or timed out
        else if (snapshot.hasError) {
          return Center(child: Text('Oops! ${snapshot.error}'));
        }
        // Show "no data" message if list is empty
        else if (snapshot.data == null || snapshot.data!.isEmpty) {
          return const Center(child: Text('No student records found.'));
        }
        // Render the list when we have valid data
        else {
          return ListView(
            children: snapshot.data!
                .map((data) => Column(
                      children: <Widget>[
                        GestureDetector(
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Padding(
                                padding: const EdgeInsets.fromLTRB(20, 5, 0, 5),
                                child: Text(
                                  data.studentName,
                                  style: const TextStyle(fontSize: 21),
                                  textAlign: TextAlign.left,
                                ),
                              )
                            ],
                          ),
                        ),
                        const Divider(color: Colors.black),
                      ],
                    ))
                .toList(),
          );
        }
      },
    );
  }
}

Key Improvements:

  • Timeout Handling: The API request fails gracefully after 5 seconds, stopping the indicator and showing a user-friendly timeout message.
  • Empty Data Coverage: If the database returns no records, we display a clear message instead of an empty screen.
  • Robust State Checks: We explicitly handle waiting, error, and empty states to cover all edge cases.
  • Type Safety: Fixed the missing generic type in the State class for better Flutter compliance.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:21:21