从流提供程序更新特定的小部件

时间:2020-02-06 15:03:40

标签: flutter

我的情况是,我有一个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,
        )
      ],
    );
  }
}

0 个答案:

没有答案