Flutter 在颤振中执行初始网络请求的正确方法是什么?

Flutter 在颤振中执行初始网络请求的正确方法是什么?,flutter,flutter-layout,flutter-http,Flutter,Flutter Layout,Flutter Http,我有以下代码,用于获取屏幕的初始数据,这个SchedulerBinding似乎是一个黑客行为,但是如果我删除它,请求数据就会丢失 我认为这是因为小部件(streamBuilders等)尚未构建 有什么办法可以解决这个问题吗 全屏代码: 完整的bloc代码:您可以在initState方法中异步加载数据,同时可以显示加载程序或消息。加载数据后,调用setState重新绘制小部件 以下是一个例子: import 'package:flutter/material.dart'; void main(

我有以下代码,用于获取屏幕的初始数据,这个SchedulerBinding似乎是一个黑客行为,但是如果我删除它,请求数据就会丢失

我认为这是因为小部件(streamBuilders等)尚未构建

有什么办法可以解决这个问题吗

全屏代码:


完整的bloc代码:

您可以在initState方法中异步加载数据,同时可以显示加载程序或消息。加载数据后,调用setState重新绘制小部件

以下是一个例子:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  createState() => new MyWidgetState();
}

class MyWidgetState extends State<MyWidget> {
  String _data;
  
  Future<String> loadData() async {
    // Simulate a delay loading the data
    await Future<void>.delayed(const Duration(seconds: 3));

    // Return the data
    return "This is your data!";
  }
  
  @override
  initState() {
    super.initState(); 

    // Call loadData asynchronously   
    loadData().then((s) { 
      // Data has loaded, rebuild the widget
      setState(() { 
        _data = s; 
      });
    });
  }
  
  @override
  Widget build(BuildContext context) {
    if (null == _data) {
      return Text("Loading...");
    }
    
    return Text(_data);
  }
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
正文:中(
子项:MyWidget(),
),
),
);
}
}
类MyWidget扩展了StatefulWidget{
@凌驾
createState()=>新建MyWidgetState();
}
类MyWidgetState扩展了状态{
字符串数据;
Future loadData()异步{
//模拟加载数据的延迟
等待未来。延迟(持续时间(秒:3));
//返回数据
return“这是您的数据!”;
}
@凌驾
initState(){
super.initState();
//异步调用loadData
loadData()。然后((s){
//数据已加载,请重新生成小部件
设置状态((){
_数据=s;
});
});
}
@凌驾
小部件构建(构建上下文){
如果(空==\u数据){
返回文本(“加载…”);
}
返回文本(_数据);
}
}
您可以在中测试它

它的工作原理如下:

  • initState将异步调用loadData,然后构建方法将绘制小部件
  • 当loadData返回时,对setState的调用将重新绘制小部件
  • 使用StreamBuilder

    以下示例使用StreamBuilder显示加载后的数据:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: MyWidget(),
            ),
          ),
        );
      }
    }
    
    class MyWidget extends StatefulWidget {
      @override
      createState() => new MyWidgetState();
    }
    
    class MyWidgetState extends State<MyWidget> {
      // Create a stream and execute it
      final Stream<String> _myStream = (() async* {
        // Simulate a delay loading the data
        await Future<void>.delayed(const Duration(seconds: 3));
        
        // Return the data
        yield "This is your data!";
      })();
      
      @override
      Widget build(BuildContext context) {
        return StreamBuilder<String>(
          stream: _myStream,
          builder: (BuildContext context, s) {  
            String result;
            
            if (s.hasError) {
              result = "Error";
            }
            else {
              if (s.connectionState == ConnectionState.done) {
                result = s.data; 
              }
              else {
                result = "Loading...";
              }
            }
            
            return Text(result);
          }
        );
      }
    }
    
    导入“包装:颤振/材料.省道”;
    void main(){
    runApp(MyApp());
    }
    类MyApp扩展了无状态小部件{
    @凌驾
    小部件构建(构建上下文){
    返回材料PP(
    家:脚手架(
    正文:中(
    子项:MyWidget(),
    ),
    ),
    );
    }
    }
    类MyWidget扩展了StatefulWidget{
    @凌驾
    createState()=>新建MyWidgetState();
    }
    类MyWidgetState扩展了状态{
    //创建一个流并执行它
    最终流_myStream=(()异步*{
    //模拟加载数据的延迟
    等待未来。延迟(持续时间(秒:3));
    //返回数据
    产生“这是你的数据!”;
    })();
    @凌驾
    小部件构建(构建上下文){
    返回流生成器(
    流:_myStream,
    生成器:(BuildContext上下文,s){
    字符串结果;
    如果(s.hasError){
    result=“Error”;
    }
    否则{
    如果(s.connectionState==connectionState.done){
    结果=s.数据;
    }
    否则{
    结果=“加载…”;
    }
    }
    返回文本(结果);
    }
    );
    }
    }
    

    希望这能有所帮助:)

    根据docs addPostFrame call callback,SchedulerBing不是一种黑客行为,只有一次,如果您删除它,您的流将永远无法获取数据 但您可以在InState中调用流加载

    void initState(){
    super.initState();
    _mblock.loadSpotMock();
    }
    
    您不能在initstate中加载数据吗?请稍后再试,数据仍然缺失。可能我可以在createState中运行request,并将初始数据传递到sate,但不确定。正如我在上面所评论的,它不起作用。您需要向我们提供有关loadSpotMock和所有widgetPosted全屏/bloc代码的更多信息,请查看原始问题。如果我使用states,它会起作用,但是我使用streams和streamBuilders更新ui,所以当我收到新数据时,它应该更新,但它不是这样工作的。@Void也许你应该发布你的代码而不是屏幕截图。给我一点时间,我将创建一个注册的初始问题,看一看look@Void你的阵营永远不会有结果。。?我正在将示例代码更改为使用StreamBuilder,请给我几分钟时间。