Flutter Trying to fire a showModalBottomSheet myst

2019-09-02 08:45发布

问题:

I question myself sometimes, whether I'm dumb, or Dart (Flutter) is weird.

How does this not work?

I'm using https://github.com/apptreesoftware/flutter_google_map_view

I show a map, and have added markers.

Since the package supports listeners, when a marker is tapped, I want to show a modal.

Does the listener work? Yep, because the print statement happens.

Does the modal work? I don't know. No error shows, nothing!

mapView.onTouchAnnotation.listen((annotation) {
  print(annotation);
  showModalBottomSheet<void>(
    context: context,
    builder: (BuildContext context) {
      return Container(
        height: 260.0,
        child: Text('Text'),
      );
    },
  );
});

Please, what is the magic bullet?

Edit

Lemme thrown in more flesh. This is my Scaffold widget.

MapView mapView = new MapView();  

@override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        key: scaffoldKey,
        appBar: new AppBar(
          title: new Text('Map View Example'),
        ),
        body: new Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            showMap(context),
          ],
        ),
      ),
    );

And showMap(...) looks like this:

 showMap(context) {
    mapView.show(
      new MapOptions(
          mapViewType: MapViewType.normal,
          showUserLocation: true,
          showMyLocationButton: true,
          showCompassButton: true,
          initialCameraPosition:
              new CameraPosition(new Location(5.6404963, -0.2285315), 15.0),
          hideToolbar: false,
          title: "Dashboard"),
      // toolbarActions: [new ToolbarAction("Close", 1)],
    );
    mapView.onMapReady.listen((_) {
      mapView.setMarkers(_markers);
    });
    mapView.onTouchAnnotation.listen((annotation) {
      print(annotation);
      showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) {
          return Container(
            height: 260.0,
            child: Text('Text'),
          );
        },
      );
    });
  }

回答1:

The reason you've having issues is that your context doesn't contain a scaffold. If you look what you're doing in your code, your context actually comes from the widget enclosing your scaffold.

YourWidget <------------ context
  MaterialApp
    Scaffold
      AppBar
      Column
        showMap....

There are a couple of ways to get around this. You can use a Builder widget something like this:

    body: new WidgetBuilder(
      builder: (context) => new Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          showMap(context),
        ],
      )
    ),

in which case the context is actually rooted below the scaffold.

YourWidget 
  MaterialApp
    Scaffold
      AppBar
      Builder <------------ context
        Column
          showMap....

However, what I would actually recommend is breaking your class into multiple classes. If your build function gets large enough you have to separate it out into another function (that's only used once), there's a good chance you need a new widget!

You could either make a body widget (probably Stateless), or a widget just for showing the map (Stateless or Stateful depending on your needs)... or more likely both!

Now as to why you're not seeing any errors... are you running in debug or release mode (if you're in debug mode there should be a little banner in the top right of the screen)? If you're in release mode it might ignore the fact that there is no scaffold in the context and fail silently, whereas in debug mode it should throw an assertion error. Running from the IDE or with flutter run generally runs in debug mode, but you may have changed it.



标签: dart flutter