首页 > 解决方案 > 使用 Flutter 中的 get_it 包导航出屏幕并返回时,StreamBuilder 中不会收到流中的数据

问题描述

我试图使用 get_it 和流实现的目标是用户能够扫描条形码,然后将条形码添加到流中。离开扫描屏幕后,流中的项目会通过流生成器看到,但是当我退出 viewResults 屏幕并重新输入时,只显示加载指示符,并且看不到流中的数据。

我在查看结果时手动将 2 项数据添加到流中,然后用户能够扫描条形码并且应用程序导航回 viewResults 屏幕,这确实显示了添加到流中的数据,但是一旦我回到家并再次打开 vewResults 页面,加载指示器继续显示,并且在我 resetLazySingleton() 并返回之前没有看到任何数据,然后只显示 2 个手动添加的条形码。

main.dart 代码:

final GetIt locator = GetIt.I;
void setupLocator() {
  locator.registerLazySingleton<StreamData>(() => StreamData());
}

查看模型代码:

class StreamData {

  final StreamController<List<ScansData>> _scanModel = StreamController.broadcast(); // privated
  Stream<List<ScansData>> get outScanList => _scanModel.stream;
  Sink<List<ScansData>> get _inScanList => _scanModel.sink; // privated

  List<ScansData> _barcodeData = [];

  StreamData() {
    outScanList.listen((data) { _barcodeData = data; },
      onError: (e) { print(e); }
    ); 

    Future.delayed(const Duration(seconds: 1)).then((_) {
      _inScanList.add([
        ScansData(
          count: 0,
          barcode: 'Test',
          date: DateTime.now()
        ),
        ScansData(
          count: 1,
          barcode: 'Test',
          date: DateTime.now()
        ),
      ]);
    });
  }

  void addBarcodeScans(ScansData scanData) { // function to add data to the stream
    _barcodeData.add(scanData); 
    Future.delayed(const Duration(seconds: 0)).then((_) {
      _inScanList.add(_barcodeData);
    }); // doesnt work without future.delay somehow   
  }
}

将扫描添加到流的扫描仪:

StreamData get _vm => GetIt.I<StreamData>(); // at top of page
//once scan is done:
return showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: const Text('Scan Again?'),
              content: Text('Result: ${scanData.code}'),
              actions: [
                // ignore: deprecated_member_use
                FlatButton(
                  child: const Text('Retry'),
                  onPressed: () {
                    setState(() => this.barcode = null);
                    controller.resumeCamera();
                    Navigator.of(context).pop();
                } ),
                // ignore: deprecated_member_use
                FlatButton(
                  child: const Text('Continue'),
                  onPressed: () { 
                    controller.stopCamera();
                    final addToStream = ScansData( 
                      count: 3,
                      barcode: barcodeData,
                      date: DateTime.now(),
                    ); 
                    _vm.addBarcodeScans(addToStream); // added here
                    Navigator.of(context).push(MaterialPageRoute(builder: (_) => ScannerResultsTest()));
                    setState(() => this.barcode = null);
                  },
                )
              ],
            );
          }
        );

查看结果屏幕:

StreamData get _vm => GetIt.I<StreamData>(); // top of page
// stream builder to show data:
Padding(
  padding: const EdgeInsets.only(top: 300),
  child: StreamBuilder<List<ScansData>>(
            stream: _vm.outScanList, 
            builder: (context, snapshot){
              if (!snapshot.hasData){
                return const Center(child: CircularProgressIndicator());
              }
              final barcodeData = snapshot.data;
              return ListView.builder(
                itemCount: barcodeData.length,
                itemBuilder: (BuildContext context, int index){
                  final dataRx = barcodeData[index];
                  return Padding(
                    padding: const EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5),
                    child: Container(
                      padding: const EdgeInsets.all(10),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text('BARCODE: ${dataRx.barcode}', style: _textBar),
                          const SizedBox(height: 2),
                          Text('#${dataRx.count}\t-\t${formatDate(dataRx.date)}', style: TextStyle(color: ember0B, fontWeight: FontWeight.bold, fontSize: 16),),
                        ],
                      ),
                      decoration: const BoxDecoration(
                        color: Color.fromRGBO(207, 244, 210, 0.75),
                        borderRadius: BorderRadius.all(Radius.circular(12.0)),
                      ),
                    ),
                  );
                }
              );
            }
          ),
)

标签: flutterdartstream-builder

解决方案


推荐阅读