Flutter自定义地图标记插件custom_map_markers的使用
Flutter 自定义地图标记插件 custom_map_markers
的使用
custom_map_markers
是一个将运行时小部件转换为地图标记图标的包。
特性
此包提供了以下功能:
- 能够使用 Flutter 小部件创建运行时地图标记。
- 可以捕获任何小部件列表的图像。
开始使用
首先,在你的 pubspec.yaml
文件中添加 custom_map_markers
作为依赖项。
dependencies:
custom_map_markers: ^0.0.1
使用方法
- 将你的
GoogleMaps
小部件包装在CustomGoogleMapMarkerBuilder
中。 - 在
customMarkers
中定义每个标记及其自定义小部件。 - 一旦自定义标记准备好,它们将以
Set<Marker>
形式传递给builder
函数。
final locations = const [
LatLng(37.42796133580664, -122.085749655962),
LatLng(37.41796133580664, -122.085749655962),
];
CustomGoogleMapMarkerBuilder(
customMarkers: [
MarkerData(
marker: Marker(
markerId: const MarkerId('id-1'),
position: locations[0],
),
child: _customMarker('A', Colors.black),
),
MarkerData(
marker: Marker(
markerId: const MarkerId('id-2'),
position: locations[1],
),
child: _customMarker('B', Colors.red),
),
],
builder: (BuildContext context, Set<Marker>? markers) {
if (markers == null) {
return const Center(child: CircularProgressIndicator());
}
return GoogleMap(
initialCameraPosition: const CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
),
markers: markers,
onMapCreated: (GoogleMapController controller) {},
);
},
);
如果你不使用 Google 地图,可以使用 CustomMapMarkerBuilder
,它接受 List<Widget>
而不是 List<MarkerData>
并返回 List<Uint8List>
而不是 Set<Marker>
。这样你就可以自由地使用捕获的 PNG 图像。
注意事项
- 确保你的标记小部件有边界。
- 此包在小部件渲染后捕获 PNG 图像。如果您的小部件(如
Image.network
)需要更长时间来渲染,您可以使用screenshotDelay
参数延迟捕获过程,确保小部件正确渲染后再捕获。 - 运行项目示例时,您需要向 Android 和 iOS 目录添加有效的 Google 地图密钥。
示例代码
import 'package:custom_map_markers/custom_map_markers.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: '自定义标记示例',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: '自定义标记示例'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final locations = const [
LatLng(37.42796133580664, -122.085749655962),
LatLng(37.41796133580664, -122.085749655962),
LatLng(37.43796133580664, -122.085749655962),
LatLng(37.42796133580664, -122.095749655962),
LatLng(37.42796133580664, -122.075749655962),
];
late List<MarkerData> _customMarkers;
[@override](/user/override)
void initState() {
super.initState();
_customMarkers = [
MarkerData(
marker: Marker(
markerId: const MarkerId('id-1'),
position: locations[0],
),
child: _customMarker3('Everywhere\nis a Widgets', Colors.blue),
),
MarkerData(
marker: Marker(
markerId: const MarkerId('id-5'),
position: locations[4],
),
child: _customMarker('A', Colors.black),
),
MarkerData(
marker: Marker(
markerId: const MarkerId('id-2'),
position: locations[1],
),
child: _customMarker('B', Colors.red),
),
MarkerData(
marker: Marker(
markerId: const MarkerId('id-3'),
position: locations[2],
),
child: _customMarker('C', Colors.green),
),
MarkerData(
marker: Marker(
markerId: const MarkerId('id-4'),
position: locations[3],
),
child: _customMarker2('D', Colors.purple),
),
MarkerData(
marker: Marker(
markerId: const MarkerId('id-5'),
position: locations[4],
),
child: _customMarker('A', Colors.blue),
),
];
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
if (_customMarkers.isNotEmpty) {
_customMarkers.removeLast();
}
});
},
),
body: CustomGoogleMapMarkerBuilder(
// screenshotDelay: const Duration(seconds: 4),
customMarkers: _customMarkers,
builder: (BuildContext context, Set<Marker>? markers) {
if (markers == null) {
return const Center(child: CircularProgressIndicator());
}
return GoogleMap(
initialCameraPosition: const CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
),
markers: markers,
onMapCreated: (GoogleMapController controller) {},
);
},
),
);
}
_customMarker(String symbol, Color color) {
return Stack(
children: [
Icon(
Icons.add_location,
color: color,
size: 50,
),
Positioned(
left: 15,
top: 8,
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(10)),
child: Center(child: Text(symbol)),
),
)
],
);
}
_customMarker2(String symbol, Color color) {
return Container(
width: 30,
height: 30,
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(color: color, width: 2),
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [BoxShadow(color: color, blurRadius: 6)]),
child: Center(child: Text(symbol)),
);
}
_customMarker3(String text, Color color) {
return Container(
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(color: color, width: 2),
color: Colors.white,
borderRadius: BorderRadius.circular(4),
boxShadow: [BoxShadow(color: color, blurRadius: 6)]),
child: Center(
child: Text(
text,
textAlign: TextAlign.center,
)),
);
}
}
更多关于Flutter自定义地图标记插件custom_map_markers的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义地图标记插件custom_map_markers的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用custom_map_markers
插件来自定义地图标记的一个代码示例。custom_map_markers
插件允许你在Google Maps上添加自定义标记,这些标记可以是图片、图标或者其它复杂的Widget。
首先,确保你的pubspec.yaml
文件中已经添加了custom_map_markers
和google_maps_flutter
依赖:
dependencies:
flutter:
sdk: flutter
google_maps_flutter: ^2.0.10 # 请检查最新版本
custom_map_markers: ^0.1.0 # 请检查最新版本
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤使用custom_map_markers
插件:
- 导入必要的包:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:custom_map_markers/custom_map_markers.dart';
- 定义自定义标记的Widget:
class CustomMarker extends StatelessWidget {
final LatLng position;
CustomMarker({required this.position});
@override
Widget build(BuildContext context) {
return Container(
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blueAccent,
),
child: Center(
child: Icon(
Icons.location_on,
color: Colors.white,
),
),
);
}
}
- 创建地图并添加自定义标记:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Custom Map Markers Example'),
),
body: MapScreen(),
),
);
}
}
class MapScreen extends StatefulWidget {
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
late GoogleMapController _controller;
final Set<Marker> _markers = {};
final LatLng _center = LatLng(40.7128, -74.0060); // 纽约市
@override
Widget build(BuildContext context) {
return Stack(
children: [
GoogleMap(
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 12.0,
),
markers: _markers.toSet(),
onMapCreated: (GoogleMapController controller) {
_controller = controller;
_addMarkers();
},
),
// 自定义标记层(使用Stack覆盖在GoogleMap上)
Positioned(
top: _center.latitude * 100000 - 25, // 根据纬度简单计算Y轴位置
left: _center.longitude * 100000 - 25, // 根据经度简单计算X轴位置
child: Transform.translate(
offset: Offset(
// 这里需要更精确的计算来调整标记位置
0,
0
),
child: CustomMarker(position: _center),
),
),
],
);
}
void _addMarkers() {
// 使用Google Maps的Marker添加默认标记(可选)
setState(() {
_markers.add(Marker(
markerId: MarkerId('default_marker'),
position: _center,
infoWindow: InfoWindow(title: 'Default Marker', snippet: 'Default Marker Info'),
));
});
}
}
注意:由于custom_map_markers
插件的API可能有所不同,且直接在Google Map Widget上覆盖自定义Widget可能涉及到复杂的坐标转换和定位调整,上面的代码示例使用了Stack
和Positioned
来简单演示如何覆盖一个自定义的Widget作为标记。在实际应用中,你可能需要更精确地计算标记的位置,或者查找是否有更高级的插件或方法来实现这一功能。
此外,custom_map_markers
插件的官方文档或示例代码可能会提供更详细和精确的使用方法,建议查阅相关文档以获取最新和最佳实践。