我正在尝试在我的
android
应用程序中嵌入谷歌地图的本机 flutter
视图。我知道我们已经有了 google_map_plugin
pub.dev
但为了提高自己作为开发人员的水平,我正在尝试将原生 Android 代码集成到我的 flutter 应用程序中
这是我的飞镖代码
const myGoogleMapView = 'myGoogleMapView';
class MyGoogleMapView extends StatelessWidget {
const MyGoogleMapView({super.key});
@override
Widget build(BuildContext context) {
return Platform.isAndroid
? const AndroidView(
viewType: myGoogleMapView,
layoutDirection: TextDirection.ltr,
creationParams: null,
creationParamsCodec: StandardMessageCodec(),
)
: const UiKitView(
viewType: myGoogleMapView,
layoutDirection: TextDirection.ltr,
creationParams: null,
creationParamsCodec: StandardMessageCodec(),
);
}
}
接下来在 Android 端,我在
manifest
中添加了我的 apikey 以及互联网权限
在
MainActivity.kt
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
flutterEngine
.platformViewsController
.registry
.registerViewFactory("myGoogleMapView", MyGoogleMapViewFactory(this))
}
}
然后我创建了
MyGoogleMapViewFactory
和MyGoogleMapView
class MyGoogleMapViewFactory(private val activity: FlutterActivity) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
val creationParams = args as Map<String?, Any?>?
return MyGoogleMapView(context, viewId, creationParams,activity)
}
}
class MyGoogleMapView(context: Context, id: Int, creationParams: Map<String?, Any?>?,activity: FlutterActivity) :
PlatformView, OnMapReadyCallback {
private val mapview: MapView = MapView(context)
private var loadedCallbackPending = false
private var mMap: GoogleMap? = null
private var currentMarker: Marker? = null
override fun getView(): View {
return mapview
}
override fun dispose() {}
init {
val layoutParams: ViewGroup.LayoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
mapview.layoutParams = layoutParams
mapview.onCreate(null)
mapview.getMapAsync(this)
}
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
val myLocation = LatLng(37.7749, -122.4194)
if (currentMarker != null) {
currentMarker?.remove()
}
currentMarker = mMap?.addMarker(
MarkerOptions().position(myLocation).title("Marker Title")
)
mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(myLocation, 10f))
}
private fun invalidateMapIfNeeded() {
if (mMap == null || loadedCallbackPending) {
return
}
loadedCallbackPending = true
mMap!!.setOnMapLoadedCallback {
loadedCallbackPending = false
postFrameCallback {
postFrameCallback {
mapview.invalidate()
}
}
}
}
private fun postFrameCallback(f: Runnable) {
Choreographer.getInstance().postFrameCallback { f.run() }
}
}
我只看到一个空的谷歌地图,上面有我的标记。我 100% 确定我的 apikey 是正确的,因为我在本机
android
应用程序中使用具有相同包名称的同一个 apikey 并且它工作正常
我还检查了谷歌地图插件的代码
github
,他们写了invalidateMapIfNeeded
,我复制粘贴并尝试在不同的地方调用它,如init
,onMapReady
等,但对我不起作用
我也尝试在飞镖方面使用
Hybrid
组合物
return PlatformViewLink(
viewType: myGoogleMapView,
surfaceFactory: (context, controller) {
return AndroidViewSurface(
controller: controller as AndroidViewController,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
onCreatePlatformView: (params) {
return PlatformViewsService.initSurfaceAndroidView(
id: params.id,
viewType: myGoogleMapView,
layoutDirection: TextDirection.ltr,
creationParams: null,
creationParamsCodec: const StandardMessageCodec(),
onFocus: () {
params.onFocusChanged(true);
},
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
);
但这也行不通。当我尝试使用原生 Android 端的
TextView
或 EditText
等简单视图时,它工作得很好。不知道谷歌地图有什么问题
日志位于此处,因为我超出了文本限制
输出
我注意到的另一件事是,当我第一次运行该应用程序时,谷歌地图是空的,就像我上面显示的那样,但是如果我继续多次进行热重载,地图就会开始缓慢显示。查看此视频了解更多
此错误似乎与谷歌控制台的谷歌地图 APi 和授权有关。您是否放置了 SHa-1 并限制了 API?我记得曾经遇到过这样的错误。
此行为可能是由多种因素引起的,调试它可能需要一些调查。您可以采取以下一些步骤来诊断和解决问题:
网络连接:确保您的设备或模拟器在运行应用程序时具有活动的网络连接。 Google 地图需要互联网连接才能加载地图。
初始化:确认您在代码中正确初始化了 Google 地图组件。如果您在 Flutter 中使用 GoogleMap 小部件,您通常应该在 onMapCreated 回调中执行此操作。
错误处理:实现 Google 地图初始化的错误处理。检查地图初始化期间抛出的任何错误消息或异常,并将它们显示在应用程序的 UI 中或记录它们以进行调试。
日志和调试:使用开发人员工具和日志收集有关可能导致问题的原因的更多信息。在日志中查找与 Google 地图组件相关的任何错误消息或警告。
状态管理:确保 Flutter 应用中的状态管理设置正确。在某些情况下,热重载可能有助于通过重新初始化状态来“解决”问题。
依赖项:检查项目的依赖项并确保它们是最新的,尤其是与地图或位置服务相关的任何包。
重建过程:了解 Flutter 中的热重载和重建是如何工作的。多次重建应用程序可能会以某种方式触发地图的正确初始化过程。
插件兼容性:确保您用于 Google 地图的 Flutter 插件与您的 Flutter 版本兼容。有时,兼容性问题可能会导致意外行为。
缓存: 检查多次热重载后是否存在地图数据缓存或初始化,这可能会导致地图显示。
在不同设备上测试:尝试在不同设备或模拟器上运行您的应用程序,看看问题是否特定于特定环境。