我的情况是,我有一个GridView,其中包含不同的无状态小组件,这些小组件最终将读取来自Sensor的读数。我已经实现了StreamProvider以每15秒提供一次虚拟数据。我已经用相同的数据来更新所有阅读小部件。现在,我只想更新与要更新的传感器ID相对应的小部件。我尝试使用如下所示的选择器,但它仍会更新所有阅读小部件(出于调试目的,我将其设置为显示N / A)。如何设置构建方法,使其仅重建与即将进入读数的传感器相对应的特定小部件?我一直在尝试存储由ID键控的小部件的地图,但这似乎也不可行。
这是我的StreamProvider
class ReadingProvider {
Random _randomGenerator;
final SampleData _sampleData;
ReadingProvider(this._sampleData) {
_randomGenerator = Random();
}
Stream<Reading> readingStream() async* {
//For this demo hardcode a list of sensors to update
List<Sensor> sensors = List();
_sampleData.accountList[0].businessUnits[0].devices.forEach((device) {
device.sensors.forEach((sensor) {
sensors.add(sensor);
});
});
Units getUnitsForSensor(Sensor sensor) {
switch(sensor.sensorType) {
case SensorType.TEMP: {
return Units.FAHRENHEIT;
}
break;
case SensorType.PRESSURE: {
return Units.INH20;
}
break;
}
return null;
}
//Define how often we want to send a new reading
Duration readingInterval = Duration(seconds: 15);
while (true) {
await Future.delayed(readingInterval);
int sensorIndex = _randomGenerator.nextInt(sensors.length);
Sensor sensor = sensors[sensorIndex];
int readingValue = _randomGenerator.nextInt(100);
Reading reading = Reading();
reading.value = readingValue.toDouble();
reading.sensorId = sensor.id;
reading.unitOfMeasure = getUnitsForSensor(sensor);
yield reading;
}
}
}
然后这是我的Widget,它显示在GridView中
class ReadingWidget extends StatelessWidget {
final String label;
final Sensor sensor;
final String unit;
ReadingWidget({this.label, this.sensor, this.unit});
String getUnitString(Units units) {
String unitString = '';
switch(units) {
case Units.CELSIUS: {
unitString = '\u00b0C';
}
break;
case Units.FAHRENHEIT: {
unitString = '\u00b0F';
}
break;
case Units.INH20: {
unitString = 'inHg';
}
break;
default: {
unitString = '%';
}
}
return unitString;
}
@override
Widget build(BuildContext context) {
Reading readingProvider = Provider.of<Reading>(context);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Selector<Reading, Reading>(selector: (_, Reading reading) {
if (reading.sensorId == sensor.id) {
return reading;
} else {
return null;
}
}, builder: (_, Reading reading, __) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
reading != null ? reading.value.toString() : 'n/a',
style: regularDarkTextStyle,
),
Padding(
padding: const EdgeInsets.only(top: 2.0),
child: Text(
reading != null ? getUnitString(reading.unitOfMeasure) : '',
style: regularDarkTextStyle.copyWith(fontSize: 10),
),
)
],
);
}),
Text(
label,
style: lightTextStyle,
overflow: TextOverflow.ellipsis,
)
],
);
}
}