简体   繁体   English

如何从其父窗口小部件中调用 Map 控制器 Flutter Map 的移动方法

[英]How to call the Map Controller's move method of Flutter Map from its parent widget

So here is what I want to achieve: I want that when I click on the suggestions of my SearchDelegate it closes the search and move me on the map to the position searched所以这就是我想要实现的目标:我希望当我点击我的 SearchDelegate 的建议时,它会关闭搜索并将我从 map 移动到搜索的 position

return FutureBuilder(
        future: chargerMonument(),
        builder: (context, snaphot) {
          if (snaphot.hasData) {
            return SafeArea(
              child: Scaffold(
                appBar: AppBar(
                        actions: [
                          IconButton(
                              icon: Icon(Icons.search),
                              onPressed: () {
                                showSearch(
                                    context: context,
                                    delegate: CustomSearchDelegate(
                                        monuments, updatelocation));
                              }),
                        ],
                key: _scaffoldKey,
                body: Map(),
              }

updatelocation is the function I try to pass to the SearchDelegate to achieve what I want updatelocation 是 function 我尝试传递给 SearchDelegate 以实现我想要的

My map looks like this:我的 map 看起来像这样:

@override
Widget build(BuildContext context)
{
FutureBuilder(
              future: test(),
              builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
                List<Widget> children;
                if (snapshot.hasData) {
                  children = [
                    Flexible(
                      child: FlutterMap(
                        mapController: mapController,
                        children: [
                          LocationMarkerLayerWidget(
                            plugin: LocationMarkerPlugin(
                                centerCurrentLocationStream:
                                    _centerCurrentLocationStreamController
                                        .stream,
                                //_centerOnLocationUpdate
                                centerOnLocationUpdate:
                                  _centerOnLocationUpdate),
                          )
                        ],
                        options: MapOptions(
                          onPositionChanged:
                              (MapPosition position, bool hasGesture) {
                            if (hasGesture) {
                              setState(() => _centerOnLocationUpdate =
                                  CenterOnLocationUpdate.never);
                            }
                          },
                          plugins: [
                            PopupMarkerPlugin(),
                            ZoomButtonsPlugin(),
                            LocationPlugin(),
                            TappablePolylineMapPlugin()
                          ],
                          interactiveFlags:
                              InteractiveFlag.all & ~InteractiveFlag.rotate,
                          zoom: 18.0,
                          center: LatLng(0, 0),
                          onTap: (_) => _popupLayerController
                              .hidePopup(), // Hide popup when the map is tapped.
                        ),
                        layers: [
                          TileLayerOptions(
                            urlTemplate:
                                'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                            subdomains: ['a', 'b', 'c'],
                          ),
                          TappablePolylineLayerOptions(
                              // Will only render visible polylines, increasing performance
                              polylineCulling: true,
                              pointerDistanceTolerance: 20,
                              polylines: [
                                TaggedPolyline(
                                    points: polylines,
                                    isDotted: true,
                                    color: Colors.blue[300],
                                    strokeWidth: 4.0)
                              ],
                              onTap: (TaggedPolyline polyline) async {
                                await showDialog(
                                    context: context,
                                    builder: (_) => new AlertDialog(
                                            title: Text(destination),
                                            content: Text("Vous etes à " +
                                                distance.round().toString() +
                                                "km de votre distination !"),
                                            actions: [
                                              TextButton(
                                                  onPressed: () {
                                                    Navigator.of(context).pop();
                                                  },
                                                  child: Text("D'accord !")),
                                              TextButton(
                                                  onPressed: () {
                                                    setState(() {
                                                      polylines = [];
                                                      refresh = 360000;
                                                    });
                                                    Navigator.of(context).pop();
                                                  },
                                                  child:
                                                      Text("Effacer ce chemin"))
                                            ]));
                              },
                              onMiss: () {
                                print('No polyline was tapped');
                              }),
                          PopupMarkerLayerOptions(
                              markers: _markers,
                              popupSnap: PopupSnap.markerTop,
                              popupController: _popupLayerController,
                              popupBuilder: (BuildContext _, Marker marker) =>
                                  ExamplePopup(
                                      marker, marker.point, drawpolyline)),
                          ZoomButtonsPluginOption(
                              minZoom: 4,
                              maxZoom: 22,
                              mini: true,
                              padding: 10,
                              alignment: Alignment.bottomRight),
                          LocationOptions(onLocationUpdate: (LatLngData ld) {
                           
                          }, onLocationRequested: (LatLngData ld) {
                            if (ld == null) {
                              return;
                            }
                            mapController.move(ld.location, 16.0);
                          },
                              /* onLocationUpdate: (LatLngData ld) {},
                            onLocationRequested: (LatLngData ld) {
                              if (ld == null || ld.location == null) {
                                return;
                              }
                              /* return;
                              }
                              mapController?.move(ld.location, 16.0);*/
                              mapController.onReady.then((result) {
                                print("I AM READY");
                                mapController.move(ld.location, 16);
                              });
                              */

                              buttonBuilder: (BuildContext context,
                                  ValueNotifier<LocationServiceStatus> status,
                                  Function onPressed) {
                            return Align(
                                alignment: Alignment.bottomRight,
                                child: Padding(
                                    padding: const EdgeInsets.only(
                                        bottom: 14.0, right: 60.0),
                                    child: Container(
                                      height: 38,
                                      width: 38,
                                      child: FloatingActionButton(
                                          backgroundColor: Colors.grey,
                                          child: ValueListenableBuilder<
                                                  LocationServiceStatus>(
                                              valueListenable: status,
                                              builder: (BuildContext context,
                                                  LocationServiceStatus value,
                                                  Widget child) {
                                                switch (value) {
                                                  case LocationServiceStatus
                                                      .disabled:
                                                  case LocationServiceStatus
                                                      .permissionDenied:
                                                  case LocationServiceStatus
                                                      .unsubscribed:
                                                    return const Icon(
                                                      Icons.location_disabled,
                                                      color: Colors.white,
                                                    );
                                                    break;
                                                  default:
                                                    return const Icon(
                                                      Icons.my_location,
                                                      color: Colors.white,
                                                    );
                                                    break;
                                                }
                                              }),
                                          onPressed: () {
                                            setState(() =>
                                                _centerOnLocationUpdate =
                                                    CenterOnLocationUpdate
                                                        .always);
                                            _centerCurrentLocationStreamController
                                                .add(18);
                                          }),
                                    )));
                          })
                        ],
                      ),
                    ),

                  ];
                } else if (snapshot.hasError) {
                  children = <Widget>[
                    Icon(
                      Icons.error_outline,
                      color: Colors.red,
                      size: 60,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 16),
                      child: Text('Error: ${snapshot.error}'),
                    )
                  ];
                } else {
                  children = <Widget>[
                    SizedBox(
                      child: CircularProgressIndicator(),
                      width: 60,
                      height: 60,
                    )
                  ];
                }
                return Center(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: children,
                  ),
                );
              });
        });
  }

and the method I want updatelocation to do is something like this:我想要 updatelocation 做的方法是这样的:

 void update(double lat,double long){
    setState(() {
                        _centerOnLocationUpdate = CenterOnLocationUpdate.never;
                      });
                      mapController.move(LatLng(lat,long), 18);
  }

how can I from the parent change the child value _centerOnLocationUpdate and call on mapController move我如何从父级更改子级值 _centerOnLocationUpdate 并调用 mapController 移动

I tried to use a ValueListenableBuilder but never found out how to make it works, thank you for your time.我尝试使用 ValueListenableBuilder 但从未发现如何使其工作,谢谢您的时间。

I finally found the solution I just had to declare the function in the Map state, and use a global key to access it from the parent widget.我终于找到了解决方案,我只需要在 Map state 中声明 function,并使用全局密钥从父窗口小部件访问它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM