Flutter地图控制插件map_controller_plus的使用
Flutter地图控制插件map_controller_plus的使用
简介
map_controller_plus
是一个用于 Flutter 地图的有状态控制器。它可以帮助你管理地图上的标记(markers)、线(lines)和多边形(polygons)。这个插件是 synw's map_controller package
的一个分支,因为它已经被废弃,所以这个新的改进版本支持最新的 flutter_map
包。
如果你需要任何功能或修复,可以在 forked repository 上打开一个 issue。
使用方法
导入依赖
首先,在你的 pubspec.yaml
文件中添加 map_controller_plus
依赖:
dependencies:
flutter:
sdk: flutter
flutter_map: ^0.13.1
latlong2: ^0.8.1
map_controller_plus: ^0.7.0
然后运行 flutter pub get
来安装依赖。
基本用法
以下是一个基本的示例,展示了如何使用 map_controller_plus
控制器来管理地图上的标记、线和多边形。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:map_controller_plus/map_controller_plus.dart';
class MapPage extends StatefulWidget {
@override
_MapPageState createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
late final MapController mapController;
late final StatefulMapController statefulMapController;
late final StreamSubscription<StatefulMapControllerStateChange> sub;
@override
void initState() {
super.initState();
// 初始化控制器
mapController = MapController();
statefulMapController = StatefulMapController(mapController: mapController);
/// [重要] 监听变更流以在变更时重建地图:
/// 这将在调用 addMarker 或其他修改地图资产的方法时重建地图
sub = statefulMapController.changeFeed.listen((change) => setState(() {}));
}
@override
void dispose() {
sub.cancel();
mapController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Map Controller Plus Demo'),
),
body: SafeArea(
child: Stack(
children: [
FlutterMap(
mapController: mapController,
options: MapOptions(
center: LatLng(48.853831, 2.348722),
zoom: 11.0,
),
children: [
MarkerLayer(markers: statefulMapController.markers),
PolylineLayer(polylines: statefulMapController.lines),
PolygonLayer(polygons: statefulMapController.polygons),
],
),
// 其他控件可以放在这里
],
),
),
);
}
}
API
地图控制
-
Zoom
zoom
: 获取当前的缩放级别。zoomIn()
: 缩放级别增加 1。zoomOut()
: 缩放级别减少 1。zoomTo()
: 缩放到指定的值。
-
Center
center
: 获取当前的中心点LatLng
。centerOnPoint()
: 将地图中心移动到指定的LatLng
。
地图资产
-
Markers
addMarker()
: 在地图上添加一个命名的标记。addMarkers()
: 在地图上添加多个命名的标记。removeMarker()
: 从地图上移除一个命名的标记。removeMarkers()
: 从地图上移除多个命名的标记。markers
: 获取地图上的所有标记。namedMarkers
: 获取地图上的所有带有名称的标记。getMarker()
: 返回具有相应名称的标记。getMarkers()
: 返回具有相应名称的标记。
-
Stateful Markers (新特性,0.7 版本开始)
addStatefulMarker()
: 添加一个带有状态的标记。mutateMarker()
: 修改标记的状态。
statefulMapController.addStatefulMarker(
name: "some marker",
statefulMarker: StatefulMarker(
height: 80.0,
width: 120.0,
state: {"showText": false},
point: LatLng(48.853831, 2.348722),
builder: (BuildContext context, Map<String, dynamic> state) {
Widget w;
final markerIcon = IconButton(
icon: const Icon(Icons.location_on),
onPressed: () => statefulMapController.mutateMarker(
name: "some marker",
property: "showText",
value: !(state["showText"] as bool),
),
);
if (state["showText"] == true) {
w = Column(
children: [
markerIcon,
Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Text("Place Name", textScaleFactor: 1.3),
),
),
],
);
} else {
w = markerIcon;
}
return w;
},
),
);
-
Lines
addLine()
: 在地图上添加一条线。lines
: 获取地图上的所有线。
-
Polygons
addPolygon()
: 在地图上添加一个多边形。polygons
: 获取地图上的所有多边形。
变更流
变更流是一个包含所有地图控制器状态变化的流。你可以使用它在发生变更时更新地图:
statefulMapController.changeFeed.listen((change) => setState(() {}));
GeoJSON 数据
地图控制器可以从 GeoJSON 数据绘制地图:
void loadData() async {
print("Loading geojson data");
final data = await rootBundle.loadString('assets/airports.geojson');
await statefulMapController.fromGeoJson(
data,
markerIcon: Icon(Icons.local_airport),
verbose: true,
);
}
@override
void initState() {
super.initState();
mapController = MapController();
statefulMapController = StatefulMapController(mapController: mapController);
loadData();
sub = statefulMapController.changeFeed.listen((change) => setState(() {}));
}
瓦片层管理
预定义了一些瓦片层:
FlutterMap(
mapController: mapController,
options: MapOptions(
center: LatLng(48.853831, 2.348722),
zoom: 11.0,
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
subdomains: const ['a', 'b', 'c'],
userAgentPackageName: 'dev.fleaflet.flutter_map.example',
),
MarkerLayer(markers: statefulMapController.markers),
// 其他层可以放在这里
],
)
示例代码
以下是一个完整的示例,展示了如何使用 map_controller_plus
控制器来管理地图上的标记、线和多边形,并提供导航功能。
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:map_controller_plus/map_controller_plus.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Map Controller Demo',
routes: {
'/': (BuildContext context) => MapPage(),
'/markers': (BuildContext context) => MarkersPage(),
'/tile_layer': (BuildContext context) => TileLayerPage(),
'/stateful_markers': (BuildContext context) => StatefulMarkersPage(),
},
);
}
}
class MapPage extends StatefulWidget {
@override
_MapPageState createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
late final MapController mapController;
late final StatefulMapController statefulMapController;
late final StreamSubscription<StatefulMapControllerStateChange> sub;
@override
void initState() {
super.initState();
// 初始化控制器
mapController = MapController();
statefulMapController = StatefulMapController(mapController: mapController);
// 监听变更流
sub = statefulMapController.changeFeed.listen((change) => setState(() {}));
}
@override
void dispose() {
sub.cancel();
mapController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Map Controller Plus Demo'),
),
body: SafeArea(
child: Stack(
children: [
FlutterMap(
mapController: mapController,
options: MapOptions(
center: LatLng(48.853831, 2.348722),
zoom: 11.0,
),
children: [
MarkerLayer(markers: statefulMapController.markers),
PolylineLayer(polylines: statefulMapController.lines),
PolygonLayer(polygons: statefulMapController.polygons),
],
),
Positioned(
bottom: 20,
left: 20,
child: Column(
children: [
ElevatedButton(
onPressed: () {
statefulMapController.addMarker(
name: 'marker1',
marker: Marker(
point: LatLng(48.853831, 2.348722),
builder: (ctx) => Icon(Icons.location_on, color: Colors.red),
),
);
},
child: Text('Add Marker'),
),
ElevatedButton(
onPressed: () {
statefulMapController.addLine(
name: 'line1',
polyline: Polyline(
points: [
LatLng(48.853831, 2.348722),
LatLng(48.863831, 2.358722),
],
color: Colors.blue,
strokeWidth: 5,
),
);
},
child: Text('Add Line'),
),
ElevatedButton(
onPressed: () {
statefulMapController.addPolygon(
name: 'polygon1',
polygon: Polygon(
points: [
LatLng(48.853831, 2.348722),
LatLng(48.863831, 2.358722),
LatLng(48.873831, 2.368722),
],
color: Colors.green.withOpacity(0.5),
borderColor: Colors.green,
borderStrokeWidth: 2,
),
);
},
child: Text('Add Polygon'),
),
],
),
),
],
),
),
);
}
}
// 其他页面的实现可以根据需要添加
class MarkersPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Markers Page'),
),
body: Center(
child: Text('Markers Page Content'),
),
);
}
}
class TileLayerPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tile Layer Page'),
),
body: Center(
child: Text('Tile Layer Page Content'),
),
);
}
}
class StatefulMarkersPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stateful Markers Page'),
),
body: Center(
child: Text('Stateful Markers Page Content'),
),
);
}
}
以上代码展示了如何使用 map_controller_plus
插件来管理和控制 Flutter 地图上的各种元素。希望对你有所帮助!
更多关于Flutter地图控制插件map_controller_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图控制插件map_controller_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用Flutter中的map_controller_plus
插件来控制地图的示例代码。这个插件是对flutter_map
的增强,提供了更丰富的地图控制功能。
首先,确保你已经在pubspec.yaml
文件中添加了依赖项:
dependencies:
flutter:
sdk: flutter
flutter_map: ^0.x.x # 请根据需要替换为最新版本
map_controller_plus: ^0.x.x # 请根据需要替换为最新版本
然后,运行flutter pub get
来安装依赖。
接下来,是一个简单的示例,展示了如何使用map_controller_plus
来控制地图:
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:map_controller_plus/map_controller_plus.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MapScreen(),
);
}
}
class MapScreen extends StatefulWidget {
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
late MapControllerPlus _mapController;
@override
void initState() {
super.initState();
_mapController = MapControllerPlus(
initialPosition: LatLng(0.0, 0.0), // 初始位置
initialZoom: 2.0, // 初始缩放级别
)..addListener(() {
// 监听地图变化,例如缩放或平移
print('Map position changed: ${_mapController.position}');
});
}
@override
void dispose() {
_mapController.dispose(); // 释放资源
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Map with map_controller_plus'),
),
body: Column(
children: [
Expanded(
child: FlutterMap(
mapController: _mapController,
options: MapOptions(
center: _mapController.position,
zoom: _mapController.zoom,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c'],
),
],
),
),
ElevatedButton(
onPressed: () {
// 示例:移动到新位置
_mapController.moveTo(LatLng(40.7128, -74.0060), zoom: 13.0);
},
child: Text('Move to New York'),
),
ElevatedButton(
onPressed: () {
// 示例:缩放地图
_mapController.zoomIn();
},
child: Text('Zoom In'),
),
ElevatedButton(
onPressed: () {
// 示例:平移地图
_mapController.pan(LatLng(1, 1)); // 向右下方平移(相对当前位置)
},
child: Text('Pan Map'),
),
],
),
);
}
}
在这个示例中:
- 我们创建了一个
MapControllerPlus
实例,并在initState
中初始化了它。 - 使用
FlutterMap
组件并将mapController
属性设置为我们的_mapController
实例。 - 在UI中添加了几个按钮,用于演示如何使用
_mapController
来控制地图(移动到新位置、缩放、平移)。
这个示例展示了如何使用map_controller_plus
插件提供的API来控制地图。你可以根据需要进一步扩展这个示例,例如添加更多的地图层、标记、覆盖物等。