flutter - 使用 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)),
),
),
);
}
);
}
),
)
解决方案
推荐阅读
- python - TypeError:'bool' 对象在 NLP 上不可下标
- wordpress - 从 CSV sku,id 将产品导入 WooCommerce
- azure - Azure 逻辑应用 - 无法创建到表存储的连接
- pddl - 具有多种类型的 PDDL 谓词变量
- heroku - 到控制器导轨后端的条带 webhook 错误
- junit - 上传junit工件期间没有匹配的文件
- python - 在不同的文件夹中执行 python 输出
- angular - Patchvalue 或获取预填充的 mat-input type="datetime-local"
- javascript - 禁用浏览器滚动到错误输入
- go - 如何在cgo中使用extern c字符串