【问题标题】:Refresh ui without reload data in FutureBuilder is possible?可以在 FutureBuilder 中刷新 ui 而不重新加载数据吗?
【发布时间】:2025-11-28 00:05:01
【问题描述】:

我有一个应用程序,其 id 使用来自 api 后端的随机数据,并且我有一个浮动操作按钮来将当前数据添加到收藏夹,当我单击收藏按钮时,图标需要根据布尔值更改(它命名为记录( )在我的示例中),但我只能使用 setState(重建页面)来做到这一点,但这次整个页面的数据正在改变,因为我的 api 答案是随机的,具有相同的 url,我的意思是每当我添加或删除当前数据时页面重新加载使用另一个随机数据,我需要绕过此数据重新加载(在我的示例中为 getData() 部分)并刷新我最喜欢的按钮的图标,有什么办法可以做到这一点,我尝试使用另一个 FutureBuilder 进行浮动按钮和 setState仅记录()但结果仍然相同?

我的构造树是这样的:

 @override
  Widget build(BuildContext context) {
    return Material(
      child: FutureBuilder<Payload>(
          future: getData(_name),
          builder: (context, snapshot) {
          Future<bool> recorded()async {
              var checkFavs = await favoriteDao.findRecordById(snapshot.data.id);
              return checkFavs == null ? Future<bool>.value(true) : Future<bool>.value(false);
            }
           if (snapshot.connectionState != ConnectionState.done && firstRun == true)
              return Center(child: Image.asset("images/dice.gif"));
            if (snapshot.connectionState == ConnectionState.done)
              if (snapshot.hasError)
              {
                return Scaffold(...) // error page
              }
              return Scaffold(..
              ....
              ....
              floatingActionButton:  FutureBuilder(
                            future: recorded(),
                            builder: (context, AsyncSnapshot snapshots){
                              return FloatingActionButton(
                               onPressed: () async{
                                  firstRun = false;
                                  var myrecord = Myrecord(//data details for record//)
                                  var checkFavs = await favoriteDao.findRecordById(snapshot.data.id);
                                  if (checkFavs == null) {await favoriteDao.insertRecord(myrecord);}
                                  else {await favoriteDao.deleteById(snapshot.data.id);}
                                  setState(() {
                                      recorded(); 
                                    });
                                  },
                                  child: snapshots.hasData && snapshots.data ? Icon (Icon ( Icons.favorite_border,) : Icon (Icons.favorite,)
                              };
                             )
                            )
                           ...

【问题讨论】:

    标签: flutter future setstate


    【解决方案1】:

    你不应该在 FutureBuilder 中创建 Future 而是在 initState 方法中

    @override
    void initState() {
      _getData = getData(_name)
      super.initState()
    }
    
    @override
    Widget build() {
      return FutureBuilder<Payload>(
        future: _getData,
        builder: (context, snapshot) {
          // your code
        }
      );
    }
    

    因为build()会在setState之后被调用,所以你应该把Future的创建和build方法分开

    【讨论】:

    • 实际上我使用第二个未来构建器来记录()函数,它检查数据库并返回一个布尔值,以便应用程序可以在每次刷新时检查它。但我会尝试你的建议,也许它对两者都有效。