在Navigator.pop之后,StreamBuilder不重建。

问题描述 投票:2回答:1

我有一个简单的服务,它正在跟踪当前用户的位置。

class LocationService {
  LatLng _lastLocation;
  Location location = Location();

 StreamController<LatLng> _locationController = StreamController<LatLng>();
 Stream<LatLng> get locationStream => _locationController.stream;

  LocationService() {
    location.onLocationChanged().listen((locationData) {
      LatLng location = LatLng(locationData.latitude, locationData.longitude);
      if(_lastLocation == null || _lastLocation != location) {
        _lastLocation = location;
        _locationController.add(location);
      }
    });
  }
}

然后,我使用这个服务来创建一个地图(多亏了 扑腾图),它是跟随当前用户位置的。

class SelfUpdatingMap extends StatelessWidget {
  final Icon currentPositionIcon;

  final MapController _controller = MapController();

  SelfUpdatingMap({
    this.currentPositionIcon,
  });

  @override
  Widget build(BuildContext context) => StreamBuilder<LatLng>(
        stream: LocationService().locationStream,
        builder: (context, asyncSnapshot) {
          if (asyncSnapshot.hasError || asyncSnapshot.data == null) {
            return Text('Loading...');
          }

          try {
            _controller?.move(asyncSnapshot.data, 18);
          } catch (ignored) {}
          return _createMapWidget(context, asyncSnapshot.data);
        },
      );

  Widget _createMapWidget(BuildContext context, LatLng location) => FlutterMap(
        options: MapOptions(
          center: location,
          zoom: 18,
        ),
        layers: [
          TileLayerOptions(
            urlTemplate: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png', // https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png is good too.
            subdomains: ['a', 'b', 'c'],
          ),
          MarkerLayerOptions(
            markers: [
              Marker(
                  width: 40,
                  height: 40,
                  point: location,
                  builder: (contact) => currentPositionIcon,
                ),
            ]
          ),
        ],
        mapController: _controller,
      );
}

然后,我使用 SelfUpdating 小部件在两个地方。

  • 在两个地方的小部件 第1页吾祖 第二页.
  • 而在 第三页继承人 第二页.

所以这里的情况是 。

  1. 我启动了我的应用程序,我就在 第1页. 我有我的 SelfUpdatingMap.
  2. 我叫 Navigator.pushNamed(context, '/page-2').
  3. 我叫 Navigator.pushNamed(context, '/page-3'). 我还有一个 SelfUpdatingMap.
  4. 我打了两次电话 Navigator.pop(context),我得到的是 第1页 但是SelfUpdatingMap 不更新自己了。

建造者甚至不再被调用。所以请问,这段代码有什么问题?

谢谢你!我有一个简单的服务,它可以跟踪当前用户的位置:类LocationService { LatLng _lastLocation

flutter dart stream localization bloc
1个回答
1
投票

当你推送和弹出一个页面后,构建metod并没有重新启动.我发现FlutterBluetoothSerial.instance.onStateChanged()流也有同样的问题,我找到的解决方案是将该流添加到本地静态最终变量中并使用它,而不是每次调用原来的方法(只有当该流是广播流时,你才能做到这一点,我认为)。

解决方案的例子。

class ExampleClass {
    static final Stream<LatLng> locationStream = LocationService().locationStream;
}

class SelfUpdatingMap extends StatelessWidget {
    ...
    @override
    Widget build(BuildContext context) => StreamBuilder<LatLng>(
        stream: ExampleClass.locationStream,
        builder: (context, asyncSnapshot) {
            if (asyncSnapshot.hasError || asyncSnapshot.data == null) {
                return Text('Loading...');
            }
            try {
                _controller?.move(asyncSnapshot.data, 18);
            } catch (ignored) {}
            return _createMapWidget(context, asyncSnapshot.data);
        },
    );
    ...
}

class Page3Widget extends StatelessWidget {
    ...
    @override
    Widget build(BuildContext context) => StreamBuilder<LatLng>(
        stream: ExampleClass.locationStream,
        builder: (context, asyncSnapshot) {
            //do something
        },
    );
    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.