Search code examples
flutterflutter-provider

In Flutter, is it possible to use Provider to create a listener function


So I have this provider

import 'package:flutter/material.dart';
import 'package:gotaxi_flutter/enums.dart';
import 'package:gotaxi_flutter/models/google_places_models/google_places_models.dart';

class PlaceInfo {
  GooglePlace place;
  bool isDestination;
  PlaceInfo(this.place, this.isDestination);
}

class RideInfoProvider with ChangeNotifier {
  CurrentRideScreen _currentRideScreen = CurrentRideScreen.none;
  PlaceInfo? _place;

  PlaceInfo? get place => _place;

  CurrentRideScreen get currentRideScreen => _currentRideScreen;

  void setCurrentRideScreen(CurrentRideScreen screen) {
    _currentRideScreen = screen;
    notifyListeners();
  }

  //set origin or destination locations
  void setPlace(GooglePlace place, bool isDestination) {
    _place = PlaceInfo(place, isDestination);
    notifyListeners();
  }
}

How can I create something similar to the following inside my widget:

@override
  void initState() {
    super.initState();

    _rideInfoProvider = RideInfoProvider();

    _rideInfoProvider.addListener(() {
      print("RideInfoProvider changed");
      if (_rideInfoProvider.place != null) {
        print(_rideInfoProvider.place);
        //run other functions or instances that exist in this widget and may utilize the place variable
      }
    });

}

Because otherwise, I have to move the whole listener logic and variables to the provider.


Solution

  • You could add and remove your listener based on the stateful widget lifecycle. This means that myListenerFunction will be called on each call to notifyListeners() from RideInfoProvider until the widget gets disposed. Do add the listener as a separate function in order to be able to remove it later passing the same reference (to the function).

    And as @josip-domazet commented I would not recommend using a consumer for this as that would call the myListenerFunction from inside the build method of a widget, so it would be called each time flutter repaints that widget, instead of only when a new change is made in the notifier.

    @override
      void initState() {
        super.initState();
    
        _rideInfoProvider = context.read<RideInfoProvider>();
    
        _rideInfoProvider.addListener(myListenerFunction);
    
    }
    
    
    @override
      void dispose() {
        super.dispose();
    
        _rideInfoProvider.removeListener(myListenerFunction);
    
    }