Flutter 中的 Google 地图相机位置更新问题

Vay*_*uit 1 google-maps flutter google-maps-flutter

我正在使用 Flutter 构建一个基于地图的应用程序。所以我使用谷歌地图包,一切正常。但是,我尝试添加一个 FloatingActionButton 以将地图重新​​定位到我的位置,但在这里,我遇到了问题。首先,地图没有重新定位到我的位置,其次,我收到了可怕的红色错误。这是代码、flutter doctor 和错误代码。

\n

我的代码:

\n
import 'package:flutter/material.dart';\nimport 'package:google_maps_flutter/google_maps_flutter.dart';\nimport 'package:provider/provider.dart';\nimport 'package:spotycar/providers/location_service.dart';\n\nimport '../../models/user_location.dart';\n\nclass MapWidget extends StatefulWidget {\n  MapWidget({@required Key key}) : super(key: key);\n\n  @override\n  _MapWidgetState createState() => _MapWidgetState();\n}\n\nvar locationClicked = false;\n\nclass _MapWidgetState extends State<MapWidget> {\n  @override\n  Widget build(BuildContext context) {\n    CameraUpdate cameraUpdate;\n    GoogleMapController mapController;\n    var location = Provider.of<UserLocation>(context);\n    final provider = Provider.of<LocationService>(context);\n    final double _zoom = 17.0;\n    final double _tilt = 37.0;\n    var _coord;\n\n    if (provider.loadedLocation) {\n      _coord = LatLng(location.latitude, location.longitude);\n      cameraUpdate = CameraUpdate.newCameraPosition(CameraPosition(\n        target: _coord,\n        bearing: location.heading,\n        zoom: _zoom,\n        tilt: _tilt,\n      ));\n    }\n\n    if (locationClicked == true) {\n      mapController.moveCamera(\n        CameraUpdate.newCameraPosition(\n          CameraPosition(\n            target: _coord,\n            bearing: location.heading,\n            zoom: _zoom,\n            tilt: _tilt,\n          ),\n        ),\n      );\n      setState(() {\n        locationClicked = false;\n      });\n    }\n\n    return Scaffold(\n      body: !provider.loadedLocation\n          ? Center(\n              child: CircularProgressIndicator(\n                valueColor: AlwaysStoppedAnimation<Color>(Colors.purple),\n              ),\n            )\n          : GoogleMap(\n              onMapCreated: (GoogleMapController controller) {\n                mapController = controller;\n                mapController.animateCamera(cameraUpdate);\n              },\n              myLocationEnabled: true,\n              myLocationButtonEnabled: false,\n              zoomControlsEnabled: false,\n              initialCameraPosition: CameraPosition(\n                target: _coord,\n                zoom: _zoom,\n                tilt: _tilt,\n              ),\n              rotateGesturesEnabled: true,\n            ),\n    );\n  }\n}\n\nclass LocationRechercheWidget extends StatefulWidget {\n  @override\n  _LocationRechercheWidgetState createState() =>\n      _LocationRechercheWidgetState();\n}\n\nclass _LocationRechercheWidgetState extends State<LocationRechercheWidget> {\n  @override\n  Widget build(BuildContext context) {\n    return FloatingActionButton(\n      child: Icon(\n        Icons.location_searching,\n        color: Colors.purple,\n        size: 25,\n      ),\n      backgroundColor: Colors.white,\n      onPressed: () {\n        setState(() {\n          locationClicked = true;\n        });\n      },\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我的颤振医生:

\n
[\xe2\x88\x9a] Flutter (Channel master, 1.20.0-3.0.pre.124, on Microsoft Windows [version 10.0.18362.900], locale fr-FR)\n    \xe2\x80\xa2 Flutter version 1.20.0-3.0.pre.124 at C:\\flutter\n    \xe2\x80\xa2 Framework revision ec3368ae45 (2 days ago), 2020-07-02 01:58:01 -0400\n    \xe2\x80\xa2 Engine revision 65ac8be350\n    \xe2\x80\xa2 Dart version 2.9.0 (build 2.9.0-20.0.dev f8ff12008e)\n\n \n[\xe2\x88\x9a] Android toolchain - develop for Android devices (Android SDK version 29.0.2)\n    \xe2\x80\xa2 Android SDK at C:\\Users\\adrie\\AppData\\Local\\Android\\sdk\n    \xe2\x80\xa2 Platform android-29, build-tools 29.0.2\n    \xe2\x80\xa2 Java binary at: C:\\Program Files\\Android\\Android Studio1310\\jre\\bin\\java\n    \xe2\x80\xa2 Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)\n    \xe2\x80\xa2 All Android licenses accepted.\n\n[\xe2\x88\x9a] Android Studio (version 3.6)\n    \xe2\x80\xa2 Android Studio at C:\\Program Files\\Android\\Android Studio1310\n    \xe2\x80\xa2 Flutter plugin version 45.1.1\n    \xe2\x80\xa2 Dart plugin version 192.7761\n    \xe2\x80\xa2 Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)\n\n[\xe2\x88\x9a] VS Code (version 1.46.1)\n    \xe2\x80\xa2 VS Code at C:\\Users\\adrie\\AppData\\Local\\Programs\\Microsoft VS Code\n    \xe2\x80\xa2 Flutter extension version 3.12.1\n\n[\xe2\x88\x9a] Connected device (1 available)\n    \xe2\x80\xa2 Mi Note 10 (mobile) \xe2\x80\xa2 53bd04cc \xe2\x80\xa2 android-arm64 \xe2\x80\xa2 Android 10 (API 29)\n\n\xe2\x80\xa2 No issues found!\n
Run Code Online (Sandbox Code Playgroud)\n

当我点击 FloatingActionButton 时出现错误:

\n
\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY WIDGETS LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following NoSuchMethodError was thrown building MapWidget-[#2721f](dirty, dependencies:\n[InheritedProvider<UserLocation>, InheritedProvider<LocationService>], state:\n_MapWidgetState#50617):\nThe method 'moveCamera' was called on null.\nReceiver: null\nTried calling: moveCamera(Instance of 'CameraUpdate')\nThe relevant error-causing widget was:\n  MapWidget-[#2721f]\n  \nlib\\screen\\map_screen.dart:20\nWhen the exception was thrown, this was the stack:\n#0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:51:5)\n#1      _MapWidgetState.build \npackage:spotycar/\xe2\x80\xa6/map_screen/map_widget.dart:39\n#2      StatefulElement.build \npackage:flutter/\xe2\x80\xa6/widgets/framework.dart:4663\n#3      ComponentElement.performRebuild \npackage:flutter/\xe2\x80\xa6/widgets/framework.dart:4546\n#4      StatefulElement.performRebuild \npackage:flutter/\xe2\x80\xa6/widgets/framework.dart:4719\n#5      Element.rebuild \npackage:flutter/\xe2\x80\xa6/widgets/framework.dart:4262\n#6      BuildOwner.buildScope \npackage:flutter/\xe2\x80\xa6/widgets/framework.dart:2667\n#7      WidgetsBinding.drawFrame \npackage:flutter/\xe2\x80\xa6/widgets/binding.dart:866\n#8      RendererBinding._handlePersistentFrameCallback \npackage:flutter/\xe2\x80\xa6/rendering/binding.dart:286\n#9      SchedulerBinding._invokeFrameCallback \npackage:flutter/\xe2\x80\xa6/scheduler/binding.dart:1115\n#10     SchedulerBinding.handleDrawFrame \npackage:flutter/\xe2\x80\xa6/scheduler/binding.dart:1054\n#11     SchedulerBinding._handleDrawFrame \npackage:flutter/\xe2\x80\xa6/scheduler/binding.dart:970\n#15     _invoke  (dart:ui/hooks.dart:253:10)\n#16     _drawFrame  (dart:ui/hooks.dart:211:3)\n(elided 3 frames from dart:async)\n
Run Code Online (Sandbox Code Playgroud)\n

Vay*_*uit 19

要解决此问题,您需要使用 Completer 而不是简单的 GoogleMapController。

当你实例化它时:

Completer<GoogleMapController> _controller = Completer();
Run Code Online (Sandbox Code Playgroud)

然后在onMapCreatedGoogleMap 小部件内的方法中:

onMapCreated: (GoogleMapController controller) {
      _controller.complete(controller);
      ...
},
Run Code Online (Sandbox Code Playgroud)

每当你想改变相机位置时:

Future<void> moveCamera() async {
  final GoogleMapController controller = await _controller.future;
  controller.moveCamera(CameraUpdate.newCameraPosition(CameraPosition(
    target: LatLong(..., ...),
    zoom: ...,
  )));
}
Run Code Online (Sandbox Code Playgroud)

而你应该很好!