【问题标题】:Flutter - How can I call setState when a future builder has completed?Flutter - 当未来的构建器完成时,我如何调用 setState?
【发布时间】:2020-06-18 08:19:38
【问题描述】:

我有一个小部件,它正在从我的其他类之一(booruHandler)获取数据,我正在使用未来构建器的未来搜索功能,但我需要多次调用它,但只有在未来构建器有完成后,我在另一个小部件中使用类似的未来构建器,并在发生操作时使用 setState 再次调用它以增加 widget.pageNum。有没有办法让 setState 在未来的构建者完成构建时被调用?我尝试将 setState 放在 futurebuilder 中,如果 connectionState 完成则调用它,但这不起作用

class SnatcherProgressPage extends StatefulWidget {
  String tags,amount,timeout;
  int pageNum=0;
  int count=0;
  SnatcherProgressPage(this.tags,this.amount,this.timeout);
  @override
  _SnatcherProgressPageState createState() => _SnatcherProgressPageState();
}

class _SnatcherProgressPageState extends State<SnatcherProgressPage> {
  static int limit, count;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    if (int.parse(widget.amount) <= 100){limit = int.parse(widget.amount);} else {limit = 100;}
  }
  BooruHandler booruHandler = new GelbooruHandler("https://gelbooru.com", limit);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Snatching"),
      ),
      body: FutureBuilder(
          future: booruHandler.Search(widget.tags,widget.pageNum),
          builder: (context, AsyncSnapshot snapshot){
              switch(snapshot.connectionState){
                case ConnectionState.active:
                  return Text("Snatching");
                  break;
                case ConnectionState.done:
                  if (snapshot.data.length < int.parse(widget.amount)){
                    // Inc pagenum to get more data
                    // Call the writer function on all of the data
                  }
                  return Text(snapshot.data.length.toString());
                  break;
                case ConnectionState.waiting:
                  return CircularProgressIndicator();
                  break;
                case ConnectionState.none:
                  return Text("hmmmmmm");
                  break;
              }
              return Text("hmmmmmm");
            },
          ),
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    很好的例子可能是这样的:

    final navigatorKey = GlobalKey<NavigatorState>();
    
    void main() => runApp(
      MaterialApp(
        home: HomePage(),
        navigatorKey: navigatorKey, // Setting a global key for navigator
      ),
    );
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: SafeArea(
              child: Center(
                  child: Text('test')
              )
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: showMyDialog, // Calling the function without providing it BuildContext
          ),
        );
      }
    }
    
    void showMyDialog() {
      showDialog(
          context: navigatorKey.currentContext,
          builder: (context) => Center(
            child: Material(
              color: Colors.transparent,
              child: Text('Hello'),
            ),
          )
      );
    }
    

    showMyDialog() 可以在任何地方使用,包括静态实用程序类、数据库连接类等...

    【讨论】:

      【解决方案2】:

      更新时回拨pageNum

      class SnatcherProgressPage extends StatefulWidget {
        final NumberCallBack onPageNumUpdated;
      }
      // ...
       setState((){
         onPageNumUpdated(/* the number */);
       });
      // ...
      
      typedef NumberCallBack = void Function(int number);
      

      或使用state management

      【讨论】:

      • setState 应该放在哪里??只有在未来的建造者完成建造并且满足条件时才需要调用它
      • 在未来构建器连接状态完成时调用setState
      • @Kahou 你不能在 FutureBuilder 中调用 setState。
      猜你喜欢
      • 2020-08-14
      • 2020-06-18
      • 2021-12-21
      • 1970-01-01
      • 2018-10-28
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      相关资源
      最近更新 更多