Flutter_map: MapController does not seem to move the map.

Created on 20 Jun 2018  路  8Comments  路  Source: fleaflet/flutter_map

Hi, I'm trying to use the move of the MapController but it does not move the map. I can see the value of the map center is moved but not the tile in the background. If I move the map slightly then it jumps to the new map center. Any idea? thanks.

enhancement question

Most helpful comment

It sounds like we need to improve the docs and examples! I think it would be great to give some guidelines around the MapController and explain how it works.

All 8 comments

Can you provide some example code? Is this happening in one of the example apps? Thanks!

Hi John, Thanks for the quick reply.

It is happening in my app and I haven't tested on the example apps. I'm using Redux. So it might be an unusual scenario... But basically I raise all position change event to update the redux store with the new mapCenter. Some other actions update then this map center (loading an object to display on the map in a different location).

First problem that I had is that once the map widget is renderer, if you change the center of the map in the store and the build mehod of the widget that render the map is triggered then the map widget does not take that into account.... It only takes the value set on the MapOptions at the initial build. Updating this mapoptions center has no effect after... So what I've done is on the build of the widget that render the map i have added something like this:


  @override
  Widget build(BuildContext context) {
    Timer(Duration(milliseconds: 600),(){
      if (widget.mapCenter!=_lastCenter || widget.mapZoom!=_lastZoom){
        _mapController.move(widget.mapCenter,widget.mapZoom);
      }
    });
    return Stack(fit: StackFit.expand, children: <Widget>[
      FlutterMap(
        mapController: _mapController,
        options: MapOptions(
            zoom: this.widget.mapZoom,
            center: this.widget.mapCenter,
            onPositionChanged: (position) {
              _setLastCenter(position.center, position.zoom);
              if (position.center==widget.mapCenter && position.zoom==widget.mapZoom) return;
              // Ignore if this is the first event
              if (!this._mapHasMoved &&
                  position.center == this.widget._firstMapCenter) {
                return;
              }
              if (position.center != null && position.zoom != null) {
                _setMovedToTrue();
                widget.onViewChanged(position.center, position.zoom);
              }
            },
            onTap: (location) {
              widget.onPropertySelected(null);
            }),
  .....
}

I call a timer to center the map programmatically at the new center using the MapController. This set the flutter map widget to the position I want but the map tiles on the control are no reset. Does this helps you?

Are you using a Stateless widget? A MapController should only be used in a StatefulWidget. Otherwise, a new MapController will be created whenever the StatelessWidget is created (which can happen many times)

@AlexandreRoba - I'm using Redux as well. I spent a few hours today setting a new center: in MapOptions to no avail, until I read this thread and looked at MapController.

My approach was to create a MapController in my Redux state, and keep it the same no matter what. So in my reducer there is a lot of
mapController: prevState.mapController,
etc. That mapController is created in the initial state and stays the same after that.

I've also got a mapCenter property in my state that does change, so that's what triggers the FlutterMap to re-build.

I'm just learning Flutter and Redux, so this might be anti-pattern or what have you. It seems to work, tho. I'd like to slow down the pan a bit, but I think I can do that with multiple calls to mapController.move()

It sounds like we need to improve the docs and examples! I think it would be great to give some guidelines around the MapController and explain how it works.

Hi @EdHubbell, thanks for sharing your experience. I still havent' found a clean way to handle "animation" with redux... :( . I looked at your proposition and it looks interesting and I have couple of questions. First when you say you create the mapcontroller in the initial state, you mean on the constructor of the "Redux" state or do you mean in the InitialState of the Statefull widget of your "presentation" widget or "container" widget?
If in this the second option, what is the advantage to have the controller on the redux state because you have a statefull widget and you only need the values of the state.
I ended up converting my presentation controller into a statefull widget for everything that requires animation but this does not solve all the case. I now store in my state the previous and the new value. So when my presentation widget is built I can compute the animation but this is not perfect... I need to store at least three value for all values that are part of an animation. I store the previous state, the to be state and a flag that indicate if the animation has played... This flag is updated at the end of the animation to make sure the animation is not played multiple time if the widget is reconstructed multiple time with the same state (For example if you have a tab navigation an reopen a tab that has a step that requires to play an animation. This not map related but could help other user flutter_map and redux :)

you mean on the constructor of the "Redux" state

Yes, that's what I mean. I've got one mapController that just lives in the AppState. I should probably have it recycle each time the MapPage runs thru an init, now that I think of it. I don't think my MapPage inits more than 1x, tho.

I don't have any other experience with animations in flutter other than getting this mapController animation going. I'm still trying to figure out whether to stick with Redux or try to move toward a more compact state management system that works with Dart. So I don't have much to say on animations. I can say that one thing that worked well for me was to pass up a TickerProvider from the app up into my middleware layer. Then I can create AnimationControllers from there. I'm not sure that's where it belongs, tho.

We do need to improve the documentation (#57) , but I think we can close this since there are examples that use MapController.

Was this page helpful?
0 / 5 - 0 ratings