Flutter中FutureBuilder和StreamBuilder

在 Flutter 中,如果你想让 FutureBuilderfuture 函数再次执行,可以通过以下几种方式实现:


方法 1:使用 Key 强制重建 FutureBuilder

通过改变 FutureBuilderkey,可以强制 Flutter 重建它,从而重新执行 future 函数:

class MyWidget extends StatefulWidget {
  
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  // 使用 UniqueKey 来强制重建 FutureBuilder
  UniqueKey _futureBuilderKey = UniqueKey();

  Future<String> fetchData() async {
    // 模拟网络请求
    await Future.delayed(Duration(seconds: 2));
    return "New Data: ${DateTime.now()}";
  }

  void _refreshData() {
    setState(() {
      // 改变 key,FutureBuilder 会重新执行 future
      _futureBuilderKey = UniqueKey();
    });
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: _refreshData,
          child: Text("Refresh Data"),
        ),
        FutureBuilder<String>(
          key: _futureBuilderKey, // 关键点:改变 key 会重建 FutureBuilder
          future: fetchData(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            }
            if (snapshot.hasError) {
              return Text("Error: ${snapshot.error}");
            }
            return Text("Data: ${snapshot.data}");
          },
        ),
      ],
    );
  }
}

方法 2:使用 StatefulWidget 管理 future

StatefulWidget 中存储 future,并在需要刷新时重新调用 fetchData

class MyWidget extends StatefulWidget {
  
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Future<String>? _futureData;

  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 2));
    return "New Data: ${DateTime.now()}";
  }

  
  void initState() {
    super.initState();
    _futureData = fetchData(); // 初始化 future
  }

  void _refreshData() {
    setState(() {
      _futureData = fetchData(); // 重新赋值 future
    });
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: _refreshData,
          child: Text("Refresh Data"),
        ),
        FutureBuilder<String>(
          future: _futureData,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            }
            if (snapshot.hasError) {
              return Text("Error: ${snapshot.error}");
            }
            return Text("Data: ${snapshot.data}");
          },
        ),
      ],
    );
  }
}

方法 3:使用 StreamBuilder 替代 FutureBuilder

如果数据需要频繁刷新,可以考虑使用 Stream + StreamBuilder

class MyWidget extends StatefulWidget {
  
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final StreamController<String> _streamController = StreamController();

  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 2));
    return "New Data: ${DateTime.now()}";
  }

  void _refreshData() {
    fetchData().then((data) {
      _streamController.add(data); // 手动推送新数据到 Stream
    });
  }

  
  void initState() {
    super.initState();
    _refreshData(); // 初始化数据
  }

  
  void dispose() {
    _streamController.close();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: _refreshData,
          child: Text("Refresh Data"),
        ),
        StreamBuilder<String>(
          stream: _streamController.stream,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            }
            if (snapshot.hasError) {
              return Text("Error: ${snapshot.error}");
            }
            return Text("Data: ${snapshot.data}");
          },
        ),
      ],
    );
  }
}

总结

方法适用场景特点
改变 Key简单场景强制重建 FutureBuilder,适合一次性刷新
重新赋值 future推荐方式通过 setState 更新 future,逻辑清晰
StreamBuilder频繁刷新适合需要持续监听数据变化的场景

选择最适合你需求的方式即可!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北极象

如果觉得对您有帮助,鼓励一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值