Flutter:如何在其父内部获取子Stream构建器的更新?

时间:2019-09-01 13:06:58

标签: flutter provider

我有一个Flutter页面,其中包含一个名为 VisitsHistory 的小部件,其中包含2个名为 VisitsList Statistics

的子小部件>

子窗口小部件“ VisitsList”具有一个流构建器,该流构建器从Firestore获取数据并呈现卡列表。

我希望来自streambuilder的数据流不断更新“统计”小部件。他们俩共享同一个父母(访问记录)。

我尝试使用Streambuilder的回调通知父对象,然后父对象调用SetState(),但这给了我一个错误:setState() or markNeedsBuild called during build

我理解该错误的原因是,我在streambuilder返回应该构建的内容之前进行了回调,但是我还能在其他地方放置该回调,以便确保构建已经完成并且可以安全进行在父级中调用setState()?

N.B .:我正在使用提供程序作为状态管理

这是VisitsList窗口小部件/ StreamBuilder中的摘录


    class VisitsList extends StatelessWidget {
      final Function getDebtDataCallback;
      VisitsList(this.getDebtDataCallback);
      @override
      Widget build(BuildContext context) {
        return StreamBuilder<QuerySnapshot>(
          stream: doctorprovider.getVisitsHistory(),
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
            switch (snapshot.connectionState) {
              case ConnectionState.waiting:
                return new CircularProgressIndicator();
              default:
                if (snapshot.data.documents.isEmpty) {
                  return Text(
                    "No Visits yet",
                    style: TextStyle(color: Colors.white),
                  );
                } else {
                  //CALLBACK IS HERE 
                  getDebtDataCallback(snapshot);
                  return new ListView( ......

1 个答案:

答案 0 :(得分:0)

可以使用值更新程序将值推入父级吗? Flutter团队创建了一个股票示例应用程序来演示此功能。

https://github.com/flutter/flutter/tree/master/examples/stocks

https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple

在孩子中,您需要这个样板

class StockSettings extends StatefulWidget {
  const StockSettings(this.configuration, this.updater);

  final StockConfiguration configuration;
  final ValueChanged<StockConfiguration> updater;

  @override
  StockSettingsState createState() => StockSettingsState();
}

class StockSettingsState extends State<StockSettings> {
void _handleBackupChanged(bool value) {
    sendUpdates(widget.configuration.copyWith(backupMode: value ? BackupMode.enabled : BackupMode.disabled));
}

void sendUpdates(StockConfiguration value) {
    if (widget.updater != null)
      widget.updater(value);
}

在父级中,您传递了子级的配置更新程序,以调用父级的setState

class StocksAppState extends State<StocksApp> {
  StockData stocks;

  StockConfiguration _configuration = StockConfiguration(
    stockMode: StockMode.optimistic,
    backupMode: BackupMode.enabled,
    debugShowGrid: false,
    debugShowSizes: false,
    debugShowBaselines: false,
    debugShowLayers: false,
    debugShowPointers: false,
    debugShowRainbow: false,
    showPerformanceOverlay: false,
    showSemanticsDebugger: false
  );

  @override
  void initState() {
    super.initState();
    stocks = StockData();
  }

  void configurationUpdater(StockConfiguration value) {
    setState(() {
      _configuration = value;
    });
}

routes: <String, WidgetBuilder>{
         '/':         (BuildContext context) => StockHome(stocks, _configuration, configurationUpdater),
         '/settings': (BuildContext context) => StockSettings(_configuration, configurationUpdater)
},