-1

我有以下代码来获取屏幕的初始数据,这个 SchedulerBinding 似乎是一个 hack,但如果我删除它,请求数据就会丢失。

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

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

在此处输入图像描述

全屏代码:https ://gist.github.com/Turbozanik/7bdfc69b36fea3dd38b94d8c4fcdcc84

完整代码:https ://gist.github.com/Turbozanik/266d3517a297b1d08e7a3d7ff6ff245f

4

2 回答 2

0

SchedulerBining 不是黑客,根据文档 addPostFrame 调用回调只有一次,如果你删除它,你的流将永远不会获得数据,但你可以在 iniState 中调用你的流加载

void initState(){
 super.initState();
 _mblock.loadSpotMock();

}
于 2021-03-23T11:02:08.210 回答
0

您可以在 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);
  }
}

您可以在https://dartpad.dartlang.org中对其进行测试

它是这样工作的:

  1. initState 将异步调用 loadData,然后 build 方法将绘制小部件。
  2. 当 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);
      }
    );
  }
}

希望这可以帮助 :)

于 2021-03-23T10:58:12.460 回答