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

Flutter 点击按钮触发执行Future及FutureBuilder的实现问题

代码问题说明

你现有代码的核心问题如下:

  1. 按钮点击事件写法错误:onPressed: getData() 会在页面首次构建时直接执行方法,而不是点击才触发,应该改为传函数引用 onPressed: getData
  2. 类型强转不合法:_calculation() 返回的是 Future<String> 类型,直接用 as String 强转必然抛出类型错误,也不符合空安全规范
  3. FutureBuilder用法错误:没有传入future参数,也没有利用snapshot的状态做判断,额外维护的外层状态完全浪费了FutureBuilder的能力
  4. 缺少初始状态区分:没有把「未点击按钮的未加载状态」和「加载中状态」分开

修复后完整代码

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 明确声明可空Future类型,初始为null对应未触发请求的状态,符合空安全要求
  Future<String>? _myFuture;

  Future<String> _calculation() async {
    await Future.delayed(const Duration(seconds: 15));
    return 'Loaded';
  }

  void getData() {
    setState(() {
      // 点击按钮后才给Future赋值,触发重建后FutureBuilder才会执行异步逻辑
      _myFuture = _calculation().timeout(
        const Duration(seconds: 5),
        onTimeout: () => 'Error',
      );
    });
  }

  Widget buildThis() {
    return FutureBuilder<String>(
      future: _myFuture,
      builder: (context, snapshot) {
        // 未点击按钮的初始状态
        if (_myFuture == null) {
          return const Text('点击按钮加载数据');
        }
        // 加载中状态
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Text('Loading');
        }
        // 加载完成返回对应结果
        if (snapshot.hasData) {
          return Text(snapshot.data!);
        }
        // 异常场景兜底
        return const Text('Error');
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              MaterialButton(
                shape: const CircleBorder(),
                color: Colors.blue,
                padding: const EdgeInsets.all(16),
                child: const Icon(
                  Icons.refresh,
                  color: Colors.white,
                ),
                // 仅传函数引用,不加括号
                onPressed: getData,
              ),
              const SizedBox(height: 20),
              buildThis(),
            ],
          ),
        ],
      ),
    );
  }
}

核心逻辑说明

  • 页面初始化时_myFuture为null,FutureBuilder不会执行异步逻辑,只会显示未加载提示
  • 只有点击按钮后才会给_myFuture赋值,触发异步函数执行
  • 所有状态(未加载、加载中、加载完成、超时错误)完全通过FutureBuilder的原生能力判断,不需要额外维护数据状态,也规避了空安全问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:12:03