【问题标题】:ChangeNotifier was used after being disposedChangeNotifier 在被处理后被使用
【发布时间】:2021-11-16 09:26:57
【问题描述】:

我是 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();
  }
}

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

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

第一次可以正常使用,但是第二次进入页面并再次按下返回按钮时,它返回错误

未处理的异常:在被使用后使用了 GoogleMapsNotifier 处置。 E/flutter (13173):一旦你调用了 dispose() GoogleMapsNotifier,不能再使用了。

我该如何解决这个问题?

【问题讨论】:

    标签: flutter flutter-provider flutter-change-notifier


    【解决方案1】:

    Provider 应该在您推送的Route 内。如果您使用全局提供程序,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: (_) => ...,
      ),
    );
    

    【讨论】:

    • 好的,如果我像这样构造我的 MaterialPageRoute 以转到此页面,它不会显示错误但现在我现在可以访问此提供程序吗?在我刚刚将其声明为最终的最终 googleMapsNotifier = Provider.of(context);
    • 当您在正确的路线中时,您仍然可以使用 Provider.of(context) 访问它,不是吗?
    • 问题是现在没有任何错误,但看起来 notifylisteners() 不起作用。我可以将屏幕上的所有请求打印到GoogleMapsNotifier with ChangeNotifier 类,但没有任何内容返回到页面。如果我回到以前的 MaterialPageRoute 构建器 - 它工作正常。任何想法
    • 如果您希望更改通知程序更新以重建 UI,您必须使用 ChangeNotifierProvider。我更新了我的答案。
    猜你喜欢
    • 2021-05-29
    • 2020-03-12
    • 2021-01-23
    • 2021-01-01
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多