如何从其父widget调用Flutter Map的Map Controller的move方法

问题描述

所以这就是我想要实现的目标:我希望当我点击 SearchDelegate 的建议时,它会关闭搜索并将我在地图上移动到搜索到的位置

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 是我尝试传递给 SearchDelegate 以实现我想要的功能

我的地图如下所示:

@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,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,);
                                                    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,);
              });
        });
  }

我想要 updatelocation 做的方法是这样的:

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

我如何从父级更改子值 _centerOnLocationUpdate 和 调用 mapController move

我尝试使用 ValueListenableBuilder,但从未发现如何使其工作,谢谢您的时间。

解决方法

我终于找到了解决方案,我只需要在 Map 状态中声明函数,并使用全局键从父小部件访问它。