2

我们如何检查consumer通过接收的数据provider是否更新或更改,我想在传递给之前添加一个缓冲区来检查Lat Langgoogle_maps_flutter,我想在传递给google_maps_flutter小部件之前检查值 5 次以更新位置

Consumer<PuhserDataProvider>(builder: (context, data, child) {
          if (data.devicePusherData != null) {
            final lat = extractLat("${data.devicePusherData.gps}");
            final lang = extractLang("${data.devicePusherData.gps}");

            log.w(lat);
            log.w(lang);

            return GoogleMap(
              onMapCreated: (GoogleMapController controller) {
                _controller.complete(controller);
              },
              myLocationButtonEnabled: false,
              initialCameraPosition: CameraPosition(
                target: LatLng(lat, lang),
                zoom: 16,
              ),
              markers: [
                Marker(
                    markerId: MarkerId('0'),
                    position: LatLng(lat, lang),
                    onTap: () =>
                        setState(() => selectedPoint = LatLng(lat, lang)))
              ].toSet(),
              onTap: (point) => setState(() => selectedPoint = null),
            );
          } else {
            return Container(
              height: MediaQuery.of(context).size.height * 0.8,
              width: double.infinity,
              child: Center(child: CircularProgressIndicator()),
            );
          }
        }),

使用的提供者是更改通知提供者,默认构造函数调用推送器来获取值,调用设置器和获取器函数来检索值。

    class PuhserDataProvider extends ChangeNotifier {
  final Pusher pusher;
  Logger log = getLogger("PuhserDataProvider");
  DevicePusherData _devicePusherData;
  DevicePusherData get devicePusherData => _devicePusherData;

  OBDPuhserData _obdPusherData;
  OBDPuhserData get obdPusherData => _obdPusherData;

  PuhserDataProvider(String imei, String token, String pusherKey)
      : pusher = Pusher(
          pusherKey,
          PusherOptions(
              cluster: 'eu',
              authEndpoint: AUTH_URL,
              auth: PusherAuth(headers: {
                'Authorization': 'Bearer $token',
                'Content-Type': 'application/json',
                'Accept': 'application/json'
              })),
        ) {
    Channel channel = pusher.subscribe('private-$imei-send');

    channel.bind('obd-event',
        (data) => _setOBDData(OBDPuhserData.fromJson(json.decode(data)[0])));

    channel.bind(
        'deviceevent',
        (data) =>
            _setDeviceData(DevicePusherData.fromJson(json.decode(data)[0])));
  }

  _setDeviceData(DevicePusherData devicePusherData) {
    this._devicePusherData = devicePusherData;
    notifyListeners();
  }

  _setOBDData(OBDPuhserData obdPusherData) {
    this._obdPusherData = obdPusherData;
    notifyListeners();
  }
}
4

2 回答 2

2

你的班级应该是这样的:

PusherDataProvider with ChangeNotifier {
  final Object _value;

  set value(Object value) {
    if (value != _value) {
      _value = value;
      // Notify listeners only when data changed
      notifyListeners();
    }

    Object get value => _value;
  }
}

所以现在 yorConsumer的 builder 将在数据更改时被调用。声明一个计数器变量,它将在 builder 中检查。

于 2020-12-19T13:50:59.903 回答
1

您可以通过 02 种方式做到这一点

  1. 使用 Selector() 而不是 Consumer()。
  2. 使用 PuhserDataProvider() 类。

1. 使用 Selector() 代替 Consumer()。

相当于消费者,可以通过选择有限数量的值来过滤更新,并在它们不更改时阻止重建。


2. 使用 PuhserDataProvider() 类。

在调用 notifyListers() 之前检查您的逻辑

这里

class PuhserDataProvider extends ChangeNotifier {
  final Pusher pusher;
  Logger log = getLogger("PuhserDataProvider");


  //I changed _devicePusherData into _devicePusherDataGps
  //I dont know Data type of your .gps , so temperary i said it as Object , you need to change it
  Object _devicePusherDataGps;

  //I changed devicePusherData into devicePusherDataGps 
  //I dont know Data type of your .gps , so temperary i said it as Object , you need to change it
  Object get devicePusherDataGps => _devicePusherDataGps;

  //counter variable with default value 1 ,this will increment when each time value changed
  int counter = 1;

  PuhserDataProvider(String imei, String token, String pusherKey)
      : pusher = Pusher(
          pusherKey,
          PusherOptions(
              cluster: 'eu',
              authEndpoint: AUTH_URL,
              auth: PusherAuth(headers: {
                'Authorization': 'Bearer $token',
                'Content-Type': 'application/json',
                'Accept': 'application/json'
              })),
        ) {
    Channel channel = pusher.subscribe('private-$imei-send');

    channel.bind(
        'deviceevent',
        (data) =>
            _setDeviceData(DevicePusherData.fromJson(json.decode(data)[0])));
  }

  _setDeviceData(DevicePusherData devicePusherData) {
    if (_devicePusherDataGps == null) {
      _devicePusherDataGps = devicePusherData.gps;
    }
    else{
      if (devicePusherData.gps != _devicePusherDataGps) {
      //This will check value changes for 5 times.
        if (counter == 5) {
          counter = 1;
          this._devicePusherDataGps = devicePusherData.gps;
          notifyListeners();
        } else {
          counter++;
        }
      }
    }
    
  }

}

在上面的类中,setter 函数仅更改为设置gps值。因为在你的问题中你说你想单独检查Lat Lang 值,所以我为它创建了单独的 setter 方法。


现在在消费者小部件中,您需要更改data.devicePusherData.gpsdata.devicePusherDataGps

final lat = extractLat("${data.devicePusherDataGps}");
final lang = extractLang("${data.devicePusherDataGps}");

希望这会帮助你。如果您对以上内容有任何疑问,请发表评论,我会尽力提供帮助。(有时代码只是有语法错误,因为我没有要导入的 json 模型类)

于 2020-12-19T16:48:05.463 回答