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

Flutter点击按钮调用API时显示进度条的问题及代码修正

问题分析与修正代码

原代码的核心问题:

  • 点击按钮无反应:调用getFokatKiAdvice()后未触发UI刷新,且FutureBuilder的future参数每次build都会重新执行请求,无法与按钮点击操作关联
  • 加载状态不符合预期:FutureBuilder的加载状态仅在初始渲染时生效,点击按钮后无法重新显示加载指示器

下面是修正后的代码:

class _MyHomePageState extends State<MyHomePage> {
  String? _advice;
  bool _isLoading = false;
  String? _errorMessage;

  // 重构API调用方法,更新状态变量触发UI刷新
  Future<void> _fetchAdvice() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final response = await http.get(Uri.parse("https://api.adviceslip.com/advice"));
      if (response.statusCode == 200) {
        var resp = json.decode(response.body);
        setState(() {
          _advice = resp['slip']['advice'];
        });
      } else {
        setState(() {
          _errorMessage = "请求失败,请重试";
        });
      }
    } catch (e) {
      setState(() {
        _errorMessage = "Oye !! Thare pass Internet naahi hn !!";
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    // 页面初始化时加载第一条建议
    _fetchAdvice();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(10.0),
          child: Column(
            children: [
              const Card(
                child: ListTile(
                  title: Text(
                    "Advice for you !",
                    textAlign: TextAlign.center,
                  ),
                ),
              ),
              Card(
                child: Column(
                  children: [
                    ListTile(
                      title: _buildAdviceContent(),
                    ),
                    const SizedBox(height: 5.0),
                    ElevatedButton(
                      onPressed: _isLoading ? null : _fetchAdvice,
                      child: _isLoading 
                          ? const SizedBox(
                              width: 20,
                              height: 20,
                              child: CircularProgressIndicator(strokeWidth: 2),
                            ) 
                          : const Text("Ghe Advice !"),
                    ),
                    const SizedBox(height: 10),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  // 抽离内容构建逻辑,让代码更清晰
  Widget _buildAdviceContent() {
    if (_isLoading) {
      return const LinearProgressIndicator();
    } else if (_errorMessage != null) {
      return Text(
        _errorMessage!,
        textAlign: TextAlign.center,
        style: const TextStyle(color: Colors.red),
      );
    } else if (_advice != null) {
      return Text(
        _advice!,
        textAlign: TextAlign.center,
      );
    } else {
      return const Text("加载中...");
    }
  }
}

关键修改说明:

  1. 新增状态变量:
    • _advice:存储获取到的建议文本
    • _isLoading:控制加载状态,点击按钮后设为true,请求结束后设为false
    • _errorMessage:存储错误信息,处理网络异常或请求失败的场景
  2. 重构API方法:
    • 将原方法改为_fetchAdvice(),内部通过setState()更新状态,触发UI刷新
    • 添加异常捕获,覆盖网络错误、请求失败等异常情况
  3. 移除FutureBuilder:
    • 直接根据状态变量构建UI,避免每次build重复发起请求
    • 加载状态下按钮设为不可点击,同时替换为小型圆形加载指示器,优化用户体验
  4. 初始化加载:
    • 在initState()中调用_fetchAdvice(),实现页面加载时自动获取第一条建议

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:18:20