为什么 StreamBuilder 不更新屏幕数据

时间:2021-02-04 08:52:27

标签: flutter

请帮助我理解为什么屏幕没有使用更新的数据重建。

这是最顶层的小部件,我用 StreamBuilder 包装了 MaterialApp:

class MyApp extends StatelessWidget {
  final bloc = BlocSingleton();

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<String>(
      stream: bloc.dataStream,
      initialData: 'initial data',
      builder: (context, snapshot) {
        print('Stream updated with snapshot.data: ${snapshot.data}');
        return MaterialApp(
          routes: {
            '/': (context) {
              print('Home route activated with: ${snapshot.data}');
              return Home(data: snapshot.data);
            },
            '/my_screen': (context) {
              print('MyScreen route activated with: ${snapshot.data}');
              return MyScreen(data: snapshot.data);
            },
          },
        );
      },
    );
  }
}

这是Home屏幕,我有一个按钮可以转到MyScreen

class Home extends StatelessWidget {
  final String data;

  Home({this.data});

  @override
  Widget build(BuildContext context) {
    print('Home builded');
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
        actions: [
          MaterialButton(
            child: Text('to my_screen'),
            textColor: Colors.white,
            color: Colors.purple,
            onPressed: () {
              Navigator.of(context).pushNamed('/my_screen');
            },
          ),
        ],
      ),
      body: Container(
        alignment: Alignment.center,
        child: Text('$data'),
      ),
    );
  }
}

这是 MyScreen 屏幕,带有将更新的数据推送到流的按钮:

class MyScreen extends StatelessWidget {
  final bloc = BlocSingleton();
  final String data;

  MyScreen({this.data});

  @override
  Widget build(BuildContext context) {
    print('MyScreen builded');
    return Scaffold(
      appBar: AppBar(
        title: Text('MyScreen'),
        actions: [
          MaterialButton(
            child: Text('update stream'),
            textColor: Colors.white,
            color: Colors.purple,
            onPressed: () {
              bloc.dataSink.add('--- updated data ---');
            },
          ),
        ],
      ),
      body: Container(
        alignment: Alignment.center,
        child: Text('$data'),
      ),
    );
  }
}

所以从 Home 屏幕我按下按钮并转到 MyScreen。 控制台输出为:

I/flutter (26700): Stream updated with snapshot.data: initial data
I/flutter (26700): Home route activated with: initial data
I/flutter (26700): Home builded
I/flutter (26700): MyScreen route activated with: initial data
I/flutter (26700): MyScreen builded

然后我按下按钮更新流并在控制台中得到输出:

I/flutter (26700): Stream updated with snapshot.data: --- updated data ---
I/flutter (26700): Home route activated with: initial data
I/flutter (26700): Home builded
I/flutter (26700): MyScreen route activated with: initial data
I/flutter (26700): MyScreen builded

如您所见,屏幕使用先前数据重建:“初始数据”,但未使用更新数据重建:“--- 更新数据 ---”。

我知道屏幕可以是 StatefulWidget-s,当屏幕从堆栈中弹出时,我们可以将值返回到前一个屏幕并在那里调用 setState 来重建它。但感觉这不是最好的方法。

0 个答案:

没有答案