ChangeNotifier 被处理后被使用

Ton*_*omy 2 flutter flutter-provider flutter-change-notifier

我是 Flutter 新手,并且坚持这个问题,我有一个页面使用名为 GoogleMapsNotifier 和 ChangeNotifier 的类,当我弹出页面时,我想在该类中处理 Stream(最后一个函数)。

class GoogleMapsNotifier with ChangeNotifier {
  final geolocatorService = GeolocatorService();
  final placesService = PlacesService();
  final markerService = MarkerService();

  Position? currentLocation;
  List<PlaceSearch> searchResults = [];
  StreamController<Place> selectedLocation = BehaviorSubject<Place>();
  StreamController<LatLngBounds> bounds = BehaviorSubject<LatLngBounds>();
  late Place selectedLocationStatic;
  List<Marker> markers = <Marker>[];

  GoogleMapsNotifier() {
    setCurrentLocation();
  }

  setCurrentLocation() async {
    currentLocation = await geolocatorService.determinePosition();
    selectedLocationStatic = Place(
        geometry: Geometry(
          location: Location(
              lat: currentLocation!.latitude, lng: currentLocation!.longitude),
        ),
        name: '',
        vicinity: '');
    notifyListeners();
  }

  searchPlaces(String searchTerm) async {
    searchResults = await placesService.getAutocomplete(searchTerm);
    notifyListeners();
  }

  setSelectedLocation(String placeId) async {
    var sLocation = await placesService.getPlace(placeId);
    selectedLocation.add(sLocation);
    selectedLocationStatic = sLocation;
    searchResults = [];
    markers = [];
    var newMarker = markerService.createMarkerFromPlace(sLocation);
    markers.add(newMarker);
    var _bounds = markerService.bounds(Set<Marker>.of(markers));
    bounds.add(_bounds as LatLngBounds);
    notifyListeners();
  }

  @override
  void dispose() {
    selectedLocation.close();

    super.dispose();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个返回按钮来弹出页面,我之前用 Provider 调用了这个函数。

onTap: () async {
                    Provider.of<GoogleMapsNotifier>(context, listen: false)
                        .dispose();
                    Navigator.pop(context);
                  },
Run Code Online (Sandbox Code Playgroud)

第一次工作正常,但当我第二次进入页面并再次按“返回”按钮时,它返回错误

未处理的异常:GoogleMapsNotifier 在被处置后被使用。E/flutter (13173):一旦您在 GoogleMapsNotifier 上调用了 dispose(),就无法再使用它。

我怎样才能解决这个问题?

Lul*_*ntu 5

应该ProviderRoute你推的里面。如果您使用全局提供程序,则实例GoogleMapsNotifier将始终相同。因此,当您第二次进入该页面时,它将无法工作(因为它与您第一次已经处理的实例相同)

这是一个具体的例子

// GOOD
runApp(MaterialApp(...));

...

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => ChangeNotifierProvider<GoogleMapsNotifier>(
      create: (_) => GoogleMapsNotifier(),
      child: ...,
    ),
  ),
);


// BAD
runApp(
  ChangeNotifierProvider<GoogleMapsNotifier>(
    create: (_) => GoogleMapsNotifier(),
    child: MaterialApp(
      home: ...,
    ),
  )
);

...

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => ...,
  ),
);
Run Code Online (Sandbox Code Playgroud)