Flutter楼层地图展示插件floors_map_widget的使用
Flutter楼层地图展示插件floors_map_widget的使用
Floors Map Widget
这个插件允许你从SVG图像创建一个交互式的楼层地图。
目录
关于项目
这个插件允许你基于SVG图像创建一个交互式的楼层地图。
特性
- 基于SVG图像生成交互式地图。
- 在不同点之间创建并可视化路径。
- 配置点击块时的交互。
支持的对象类别
- shop
- parkingspace
- atmmachine
- toilet
- stairs
卫生间子类型
- male
- female
- mother_and_child
楼梯子类型
- simple
- fire_escape
- escalator
- elevator
如何使用
与库的工作分为几个阶段。
阶段1 - 添加路线点
使用Figma或其他任何SVG编辑器,创建一个楼层地图或使用现有的地图。现在,你需要准备这张地图以供FloorMapWidget使用。你需要设置路线点和入口点到房间对象。你可以使用现成的Figma扩展程序,也可以手动完成。
Figma扩展程序
放置点并将它们连接成路径。你可以阅读更详细的描述 这里。
手动实现
你可以使用圆形状或自定义形状使用路径。通过id属性进行点绑定。例如,在这个例子中,我们以两种方式创建了一个点,并将其连接到三个相邻的点。
point-43=44-39-45
│ │ └‒‒└‒‒└‒‒‒‒‒ 唯一ID的相邻邻居
│ └‒‒‒‒‒ 点的唯一ID
└‒‒‒‒‒ 对象的类 - 点
<circle id="point-43=44-39-45" cx="4.5" cy="4.5" r="4.5" fill="black"/>
<path id="point-43=44-39-45" d="M4.2 8.39999C6.52 8.39999 8.39999 6.52 8.39999 4.2C8.39999 1.88 6.52 0 4.2 0C1.88 0 0 1.88 0 4.2C0 6.52 1.88 8.39999 4.2 8.39999Z" fill="black"/>
阶段2 - 为房间对象分配正确的ID
你可以在这里看到支持的对象。 创建ID的规则与点相同。
shop-1=2
│ │ └‒‒‒‒‒ 连接入口点的唯一ID(只能有一个)
│ └‒‒‒‒‒ 对象的唯一ID
└‒‒‒‒‒ 对象的类
stairs-elevator-1=2
│ │ │ └‒‒‒‒‒ 连接入口点的唯一ID(只能有一个)
│ │ └‒‒‒‒‒ 对象的唯一ID
│ └‒‒‒‒‒ 对象的子类型(楼梯和卫生间需要)
└‒‒‒‒‒ 对象的类
完整示例
<path id="shop-3=5" d="M477.648 206.928H428.712V323.772H565.44V315H569.448V235.404H481.044H477.648V231.996V206.928Z" fill="#EEF9FE" />
阶段3 - 将库集成到你的项目中
将库添加到你的项目中,并嵌入包含必要参数的准备好的小部件。
FloorMapWidget(
// SVG Map字符串
_svgContent,
// 楼层小部件
_listWidgets,
// 用于构建路线
startIdPoint: _startPointItem?.idPoint,
endIdPoint:_endPointItem?.idPoint,
// 用于从SVG中删除点
unvisiblePoints: true,
),
要向地图添加交互对象,你需要使用FloorItemWidget初始化它们,并作为列表传递给FloorItemWidget。
FloorItemWidget(
// FloorItem
item: element,
// 函数 (FloorItem)
onTap: _handleFloorItemTap,
// 交互动画颜色变化示例
selectedColor: Colors.orange[200]!.withOpacity(0.5),
// 对象闪烁示例
// 通过这种方式,你可以突出显示地图上的某些对象。例如厕所或ATM
isActiveBlinking: false,
),
你可以使用FloorSvgParser获取对象。
final parser = FloorSvgParser(svgContent: svgContent);
// 可以从地图中获取锚点
final listPoints = parser.getPoints();
// 可以获取库支持的所有对象
final listItems = parser.getItems();
更多详情,请访问带有准备好的代码和地图的示例 这里。
如何贡献
开始前,请阅读 CONTRIBUTING.md,了解该项目的指南。
更新日志
查看 CHANGELOG.md,获取所有发布说明。
维护者
Valerij Shishov | Arthur Lokhov
该库欢迎问题和拉取请求。如果你有任何改进建议或发现bug,请随时贡献!
示例代码
import 'package:example/widgets/example_bottom_sheet.dart';
import 'package:floors_map_widget/floors_map_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
// 为了使示例更容易理解,
// 我们没有使用状态管理库。
final class SvgMapExample extends StatefulWidget {
const SvgMapExample({
super.key,
});
[@override](/user/override)
State<SvgMapExample> createState() => _SvgMapExampleState();
}
class _SvgMapExampleState extends State<SvgMapExample> {
// 为了简化示例,我们没有使用状态库,
// 因此如果变量为空,则会显示加载小部件
String? _svgContent;
// 地图元素表
List<FloorItemWidget> _listWidgets = [];
// 路径点
FloorItem? _startPointItem;
FloorItem? _endPointItem;
[@override](/user/override)
void initState() {
super.initState();
_initializeMap();
}
// 对象闪烁示例
void searchObjects<T extends FloorItem>({final FloorSubTypes? subType}) {
_listWidgets = _listWidgets.map((final item) {
if (item.item is T && (subType == null || subType == item.item.subType)) {
return item.copyWith(isActiveBlinking: true);
}
return item.copyWith(isActiveBlinking: false);
}).toList();
setState(() {});
}
// 获取信息并构建路径示例
Future<void> _handleFloorItemTap(final FloorItem floorItem) async {
await ExampleBottomSheet.showBottomSheet(
context,
floorItem,
() => _setStartPoint(floorItem),
() => _setEndPoint(floorItem),
);
}
void _setStartPoint(final FloorItem floorItem) {
setState(() {
_startPointItem = floorItem;
});
}
void _setEndPoint(final FloorItem floorItem) {
setState(() {
_endPointItem = floorItem;
});
}
Future<void> _initializeMap() async {
try {
final svgContent =
await rootBundle.loadString('assets/map_with_points_example.svg');
// 解析器初始化
final parser = FloorSvgParser(svgContent: svgContent);
// 可以从地图中获取锚点
// 忽略:未使用的局部变量
final listPoints = parser.getPoints();
// 可以获取库支持的所有对象
final listItems = parser.getItems();
// 基于FloorItem创建FloorItemWidget
final listWidgets = listItems
.map(
(final element) => FloorItemWidget(
element,
onTap: _handleFloorItemTap,
// 交互动画颜色变化示例
selectedColor: Colors.orange[200]!.withOpacity(0.5),
// 对象闪烁示例
// 通过这种方式,你可以突出显示地图上的某些对象。例如厕所或ATM
// 忽略:避免冗余参数值
isActiveBlinking: false,
),
)
.toList();
// 更新UI上接收到的数据
setState(
() {
_svgContent = svgContent;
_listWidgets = listWidgets;
_startPointItem = null;
_endPointItem = null;
},
);
} catch (e) {
debugPrint('Error initial map: $e');
setState(() {
_svgContent = null;
});
}
}
[@override](/user/override)
Widget build(final BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('示例地图小部件'),
),
body: _svgContent == null
? const Center(child: CircularProgressIndicator())
: SafeArea(
child: Stack(
children: [
// 用于缩放和移动
InteractiveViewer(
maxScale: 3,
child: FloorMapWidget(
// SVG Map字符串
_svgContent!,
// 楼层小部件
_listWidgets,
// 用于构建路径
startIdPoint: _startPointItem?.idPoint,
endIdPoint: _endPointItem?.idPoint,
// 用于从SVG中删除点
unvisiblePoints: true,
),
),
Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () => searchObjects<FloorShop>(),
icon: const Icon(Icons.store),
),
IconButton(
onPressed: () => searchObjects<FloorHygieneZone>(
subType: FloorHygieneZoneType.maleRoom,
),
icon: const Icon(Icons.wc),
),
IconButton(
onPressed: () => searchObjects<FloorHygieneZone>(
subType: FloorHygieneZoneType.motherAndChildRoom,
),
icon: const Icon(Icons.child_care),
),
IconButton(
onPressed: () => searchObjects<FloorStairs>(
subType: FloorStairsType.escalator,
),
icon: const Icon(Icons.escalator),
),
IconButton(
onPressed: () => searchObjects<FloorStairs>(
subType: FloorStairsType.elevator,
),
icon: const Icon(Icons.elevator),
),
IconButton(
onPressed: () => searchObjects<FloorAtmMachine>(),
icon: const Icon(Icons.atm),
),
IconButton(
onPressed: _initializeMap,
icon: const Icon(Icons.cancel),
),
],
),
),
],
),
),
);
}
void main() async {
runApp(
const MaterialApp(
home: SvgMapExample(),
),
);
}
更多关于Flutter楼层地图展示插件floors_map_widget的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter楼层地图展示插件floors_map_widget的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用floors_map_widget
插件来展示楼层地图的示例代码。这个示例假设你已经将floors_map_widget
添加到了你的pubspec.yaml
文件中,并且已经完成了必要的配置。
首先,确保你的pubspec.yaml
文件中包含以下依赖项:
dependencies:
flutter:
sdk: flutter
floors_map_widget: ^最新版本号 # 替换为实际版本号
然后,运行flutter pub get
来安装依赖。
接下来,是一个简单的Flutter应用示例,展示了如何使用floors_map_widget
来展示楼层地图:
import 'package:flutter/material.dart';
import 'package:floors_map_widget/floors_map_widget.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Floors Map Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FloorsMapScreen(),
);
}
}
class FloorsMapScreen extends StatefulWidget {
@override
_FloorsMapScreenState createState() => _FloorsMapScreenState();
}
class _FloorsMapScreenState extends State<FloorsMapScreen> {
// 示例楼层数据
final List<Floor> floors = [
Floor(
id: '1',
name: 'First Floor',
imageUrl: 'assets/images/floor_1.png', // 替换为你的楼层图片路径
rooms: [
Room(
id: '1_1',
name: 'Room 101',
coordinates: [
Coordinate(x: 50, y: 100),
Coordinate(x: 200, y: 100),
Coordinate(x: 200, y: 200),
Coordinate(x: 50, y: 200),
],
),
// 添加更多房间...
],
),
// 添加更多楼层...
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Floors Map'),
),
body: FloorsMapWidget(
floors: floors,
onFloorSelected: (floorId) {
print("Floor selected: $floorId");
},
onRoomSelected: (room) {
print("Room selected: ${room.name}");
},
),
);
}
}
// 定义楼层数据模型
class Floor {
final String id;
final String name;
final String imageUrl;
final List<Room> rooms;
Floor({required this.id, required this.name, required this.imageUrl, required this.rooms});
}
// 定义房间数据模型
class Room {
final String id;
final String name;
final List<Coordinate> coordinates;
Room({required this.id, required this.name, required this.coordinates});
}
// 定义坐标数据模型
class Coordinate {
final double x;
final double y;
Coordinate({required this.x, required this.y});
}
在这个示例中,我们定义了一个简单的楼层(Floor
)和房间(Room
)数据模型,以及一个坐标(Coordinate
)模型来表示房间的边界。然后,我们在FloorsMapScreen
中使用FloorsMapWidget
来展示楼层地图,并处理楼层和房间的选择事件。
请注意,你需要提供实际的楼层图片,并将路径替换为imageUrl
字段中的值。此外,你可能还需要根据实际需求调整房间坐标。
这个示例只是一个简单的起点,你可以根据需要进一步扩展和自定义FloorsMapWidget
的使用。