Flutter地图操作与展示插件mapster的使用
Flutter 地图操作与展示插件mapster的使用
Mapster 是一个对象映射库。
如何使用
步骤 1: 扩展一个 Mapper
类
你可以扩展 Mapper
类来实现从一个或多个源对象到目标对象的映射。例如,如果你只需要将一个对象映射到另一个对象,那么可以扩展 OneSourceMapper
。
class UserToUserResponseMapper extends OneSourceMapper<User, UserResponse> {
UserToUserResponseMapper(super.input);
@override
UserResponse map() {
return UserResponse(
id: source.id,
fullName: '${source.firstName} ${source.lastName}',
);
}
}
步骤 2: 创建 Mapster
实例
创建一个 Mapster
实例来管理你的映射器。
void main() {
final mapster = Mapster();
}
步骤 3: 注册所有映射器
在创建的 Mapster
实例中注册你所有的映射器。根据映射器类型(如 OneSourceMapper
, TwoSourcesMapper
等),使用 MapperMeta
的静态方法进行注册。
void main() {
final mapster = Mapster();
mapster.register(MapperMeta.one(UserToUserResponseMapper.new));
}
步骤 4: 使用 Mapster
最后,你可以使用 Mapster
来执行映射操作。
void main() {
final mapster = Mapster();
mapster.register(MapperMeta.one(UserToUserResponseMapper.new));
const user = User(
id: 1,
firstName: 'Harry',
lastName: 'Potter',
);
final userResponse = mapster.map1(user, To<UserResponse>());
print(userResponse);
}
注意,你需要传递 To<YourResultType>()
作为最后一个参数。这指定了 Mapster
应该返回的类型。
你还可以为源对象创建私有 getter,这样会更方便。
class UserUserPostToLikedPostNotification
extends ThreeSourcesMapper<User, User, Post, LikedPostNotification> {
UserUserPostToLikedPostNotification(super.input);
@override
LikedPostNotification map() {
return LikedPostNotification(
postID: _post.id,
authorID: _user1.id,
likeUserID: _user2.id,
postText: _post.text,
authorName: '${_user1.firstName} ${_user1.lastName}',
likeUserName: '${_user2.firstName} ${_user2.lastName}',
);
}
User get _user1 => source1;
User get _user2 => source2;
Post get _post => source3;
}
映射函数
Mapster
提供了九种映射方法:map1
, map2
, …, map9
。这些方法接受源对象并指定输出类型。
你可以以任何顺序传递源对象给 Mapster
的映射方法。你不需要检查特定映射器的输入对象顺序。Mapster
足够智能,可以找到合适的映射器。
class UserPostToPostResponse extends TwoSourcesMapper<User, Post, PostResponse> {
UserPostToPostResponse(super.input);
@override
PostResponse map() {
return PostResponse(
id: source2.id,
text: source2.text,
userID: source1.id,
userName: '${source1.firstName} ${source1.lastName}',
);
}
}
void main() {
final mapster = Mapster();
mapster.register(MapperMeta.two(UserPostToPostResponse.new));
const user = User(
id: 1,
firstName: 'Harry',
lastName: 'Potter',
);
const post = Post(
id: 1,
text: "The philosopher's stone",
);
// 你可以交换源对象,结果将是相同的。
final postResponse1 = mapster.map2(user, post, To<PostResponse>());
final postResponse2 = mapster.map2(post, user, To<PostResponse>());
print(postResponse1);
print(postResponse2);
}
注意,对于具有多个相同类型源对象的映射器,Mapster
会按照传递的顺序匹配输入对象。因此,如果交换多个相同类型的对象,结果可能会改变。
class UserUserPostToLikedPostNotification
extends ThreeSourcesMapper<User, User, Post, LikedPostNotification> {
UserUserPostToLikedPostNotification(super.input);
@override
LikedPostNotification map() {
return LikedPostNotification(
postID: source3.id,
authorID: source1.id,
likeUserID: source2.id,
postText: source3.text,
authorName: '${source1.firstName} ${source1.lastName}',
likeUserName: '${source2.firstName} ${source2.lastName}',
);
}
}
void main() {
final mapster = Mapster();
mapster.register(MapperMeta.three(UserUserPostToLikedPostNotification.new));
const user = User(
id: 1,
firstName: 'Harry',
lastName: 'Potter',
);
const post = Post(
id: 1,
text: "The philosopher's stone",
);
const likeUser = User(
id: 2,
firstName: 'Ronald',
lastName: 'Weasley',
);
// 你可以交换源对象,但如果交换多个相同类型的对象,结果将会改变。
final notification1 = mapster.map3(
user,
likeUser,
post,
To<LikedPostNotification>(),
);
final notification2 = mapster.map3(
likeUser,
user,
post,
To<LikedPostNotification>(),
);
print(notification1);
print(notification2);
}
优点与缺点
优点
- 不需要在使用
register
和map
函数时指定类型。 - 不需要担心参数顺序。
- 分析器能正确确定
map
函数的返回类型。 Mapster
查找合适映射器的时间复杂度为 O(1)。Mapster
在传递参数之前对参数进行排序的时间复杂度为 O(n),其中 n 是参数的数量。Mapster
没有依赖。- 不再需要通过大量映射器注入类/函数,只需注入
Mapster
。 - 不需要知道具体的映射器来进行映射。
- 可以在一个地方指定映射器。
- 可以重新定义映射器。
缺点
- 目前尚未发现。
其他特性
重新定义映射器
你可以通过再次调用 register
方法来重新定义映射器。
void main() {
final mapster = Mapster();
const user = User(
id: 1,
firstName: 'Harry',
lastName: 'Potter',
);
// 注册映射器,输入类型为 User,输出类型为 UserResponse。
mapster.register(MapperMeta.one(UserToUserResponseMapper.new));
final userResponse1 = mapster.map1(user, To<UserResponse>());
// 注册另一个映射器,输入类型和输出类型相同:
// 输入类型为 User,输出类型为 UserResponse。
mapster.register(MapperMeta.one(AnotherUserToUserResponseMapper.new));
final userResponse2 = mapster.map1(user, To<UserResponse>());
}
Mapster
根据其源类型和结果类型存储映射器。如果新的映射器具有与旧映射器相同的输入类型集(输入类型顺序无关紧要)和相同的输出类型,则 Mapster
将用新映射器替换旧映射器。
void main() {
final mapster = Mapster();
const user = User(
id: 1,
firstName: 'Harry',
lastName: 'Potter',
);
// 注册映射器,输入类型为 User,输出类型为 UserResponse。
mapster.register(MapperMeta.one(UserToUserResponseMapper.new));
final userResponse1 = mapster.map1(user, To<UserResponse>());
// 注册另一个映射器,输入类型和输出类型交换:
// 输入类型为 UserResponse,输出类型为 User。
mapster.register(MapperMeta.one(UserResponseToUserMapper.new));
// 因为第一个映射器的输入类型集包含不同的类型,而第二个映射器的输入类型集不同,
// 这两个映射器被认为是不同的。
// 我们也可以这样说:因为第一个映射器的输出类型不等于第二个映射器的输出类型,
// 这两个映射器被认为是不同的。
final user2 = mapster.map1(userResponse1, To<User>());
}
与 injectable 集成
如果你使用 injectable
包,你可以像这样注册 Mapster
和映射器:
[@module](/user/module)
abstract class MapsterModule {
[@singleton](/user/singleton)
Mapster get mapster => Mapster();
}
[@singleton](/user/singleton)
class MapsterRegistrar {
const MapsterRegistrar(this._mapster);
final Mapster _mapster;
[@postConstruct](/user/postConstruct)
void register() {
_mapster
..register(MapperMeta.one(UserToUserResponseMapper.new))
..register(MapperMeta.three(UserUserPostToLikedPostNotification.new));
}
}
更多关于Flutter地图操作与展示插件mapster的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图操作与展示插件mapster的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,mapster
插件虽然不是一个广泛认知的官方或主流地图插件(如 flutter_map
或 google_maps_flutter
),但假设它是一个用于地图操作和展示的第三方库,我们可以通过一些假设性的代码案例来展示如何使用它(请注意,以下代码是基于假设的 mapster
插件的API)。
首先,确保你已经在 pubspec.yaml
文件中添加了 mapster
依赖项(请注意,这里的依赖项名称是假设的,实际使用时需要替换为真实的插件名称):
dependencies:
flutter:
sdk: flutter
mapster: ^x.y.z # 替换为实际的版本号
然后,运行 flutter pub get
来获取依赖项。
接下来是一个基本的代码示例,展示如何在Flutter应用中使用 mapster
插件来显示和操作地图:
import 'package:flutter/material.dart';
import 'package:mapster/mapster.dart'; // 假设的导入路径
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Mapster Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MapScreen(),
);
}
}
class MapScreen extends StatefulWidget {
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
MapsterController? _controller;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mapster Demo'),
),
body: MapsterMap(
controller: _controller,
initialCameraPosition: CameraPosition(
target: LatLng(37.7749, -122.4194), // 旧金山
zoom: 12.0,
),
onMapCreated: (MapsterController controller) {
_controller = controller;
// 可以在这里添加地图标记、多边形等
_addMarker();
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 示例:移动到新的位置
_controller?.animateCamera(
CameraUpdate.newLatLngZoom(LatLng(40.7128, -74.0060), 14.0),
); // 纽约
},
tooltip: 'Move to New York',
child: Icon(Icons.location_searching),
),
);
}
void _addMarker() {
if (_controller != null) {
_controller!.addMarker(
MarkerOptions(
position: LatLng(37.7749, -122.4194),
infoWindow: InfoWindow(title: 'San Francisco'),
icon: BitmapDescriptor.defaultMarker,
),
);
}
}
}
在这个示例中,我们做了以下几件事:
- 导入
mapster
包。 - 创建一个基本的 Flutter 应用。
- 在
MapScreen
中使用MapsterMap
小部件来显示地图。 - 使用
MapsterController
来控制地图,例如添加标记和移动相机位置。 - 在地图创建完成后,通过
onMapCreated
回调获取MapsterController
实例,并添加一个标记。 - 提供一个浮动操作按钮来演示如何移动地图相机到新的位置。
请注意,由于 mapster
并非一个真实存在的Flutter插件(据我所知),上述代码是基于假设的API设计的。如果你正在使用一个具体的地图插件,请参考该插件的官方文档和API参考来编写实际代码。对于真实存在的插件,如 flutter_map
或 google_maps_flutter
,它们的用法会有所不同,但基本的概念(如地图显示、标记添加、相机控制等)是相似的。