You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
travelguideProject/src/lib/travelguideapp/ui/boundary/MapPage.dart

164 lines
6.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
class MapPage extends StatefulWidget {
@override
_MapPageState createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
int currentFloor = 0;
// 存放地图图片路径的列表
final List<String> mapImages = [
'assets/1F.png',
'assets/2F.png',
'assets/3F.png',
'assets/4F.png',
'assets/5F.png',
];
// 存放推荐路线图片路径的列表
final List<String> routeImages = [
'assets/1F-Route.png',
'assets/2F-Route.png',
'assets/3F-Route.png',
'assets/4F-Route.png',
'assets/5F-Route.png',
];
// 切换到下一楼层
void nextFloor() {
if (currentFloor < mapImages.length - 1) {
setState(() {
currentFloor++;
});
}
}
// 切换到上一楼层
void previousFloor() {
if (currentFloor > 0) {
setState(() {
currentFloor--;
});
}
}
// 显示地图弹窗
void showMapPopup() {
if (currentFloor >= 0 && currentFloor < routeImages.length) { // 检查当前楼层是否在合法范围内
showDialog( // 弹窗函数
context: context,
builder: (context) { // 创建一个弹窗使用AlertDialog
return MapPopup(
title: '${currentFloor + 1} 楼 - 推荐路线', // 设置弹窗的标题
imagePath: routeImages[currentFloor], // 选择要显示的推荐路线图片
);
},
);
}
}
@override
Widget build(BuildContext context) { // 此函数负责构建小部件的主体
return Scaffold( // 用于创建标准的应用程序页
appBar: AppBar( // 应用程序页的标题栏
title: Text('地图显示 - ${currentFloor + 1}'), // 标题栏上的标题文本,显示当前楼层
backgroundColor: Colors.green, // 标题栏的背景颜色设置为绿色
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center, // 设置子元素在垂直方向上居中对齐。
children: [
_buildImage(mapImages[currentFloor], 200, 10), // 调用 _buildImage 函数以显示当前楼层的地图图像
Row( // 用于在水平方向上排列其子元素
mainAxisAlignment: MainAxisAlignment.spaceAround, // 设置子元素在水平方向上均匀分布,具有相同的间距
children: [
_buildColumnButton(previousFloor, Icons.arrow_back, '上一楼层'), // 创建包含上一楼层按钮和标签的小部件
_buildColumnButton(showMapPopup, Icons.map, '推荐路线'), // 创建包含显示地图弹窗按钮和标签的小部件
_buildColumnButton(nextFloor, Icons.arrow_forward, '下一楼层'), // 创建包含下一楼层按钮和标签的小部件
],
)
],
),
);
}
Widget _buildImage(String imagePath, double height, double verticalOffset) { // 创建一个包含图像的小部件
return Center(
child: Padding( // 创建一个内边距小部件,用于在按钮和文本标签之间添加空白
padding: EdgeInsets.only(bottom: 30), // 设置底部内边距为30像素
child: SizedBox( // 用于限制其子元素的大小
height: height, // 设置图像的高度
child: Transform.translate( // 用于平移其子元素的位置
offset: Offset(0, verticalOffset), // 设置垂直偏移,以垂直方向上移动图像的位置
child: Transform.scale( // Transform.scale 小部件用于缩放其子元素
scale: 1.0, // 比例是1.0
child: Image.asset(imagePath), // 添加一个图像,使用传递进来的图像路径
),
),
),
),
);
}
Widget _buildColumnButton(void Function() onPressed, IconData iconData, String label) { // 创建一个垂直排列的按钮
return Column( // 垂直排列的小部件
children: [
_buildCircularButton(onPressed, iconData), // 创建一个圆形按钮,并将其添加到 Column 中
Padding( // 创建一个内边距小部件,用于在按钮和文本标签之间添加空白
padding: EdgeInsets.only(bottom: 10), // 设置底部内边距为10像素以增加按钮和文本之间的间距
child: Text(label, style: TextStyle(fontSize: 16)), // 添加文本标签,使用传递进来的文本内容
),
],
);
}
Widget _buildCircularButton(void Function() onPressed, IconData iconData) { // 创建一个圆形按钮小部件
return GestureDetector( // 包装小部件,用于监听用户的手势事件
onTap: onPressed, // 当用户点击这个按钮时,执行传递进来的回调函数
child: Container( // 创建一个容器小部件,用于包含按钮内容
width: 50, // 设置容器的宽度为50像素。
height: 50, // 设置容器的高度为50像素。
decoration: BoxDecoration( // 容器的装饰,可以定义其外观。
color: Colors.green, // 设置容器的背景颜色为绿色。
shape: BoxShape.circle, // 设置容器的形状为圆形,因为我们想要一个圆形按钮。
),
child: Center(
child: Icon(
iconData, // 创建一个图标小部件,使用传递进来的图标数据
color: Colors.white, // 设置图标的颜色为白色。
size: 30, // 设置图标的大小为30像素。
),
),
),
);
}
}
class MapPopup extends StatelessWidget { // 弹窗小部件,用于显示推荐路线的图片
final String title; // 弹窗的标题,包括楼层信息
final String imagePath; // 要显示的推荐路线图片的路径
MapPopup({required this.title, required this.imagePath});
@override
Widget build(BuildContext context) {
return AlertDialog( // 对话框组件
title: Text(title), // 设置弹窗的标题为传递进来的标题
content: SizedBox(
width: double.maxFinite, // 弹窗内容部分宽度占据最大可用空间
height: 300, // 弹窗内容部分的高度固定为 300 像素
child: PhotoView(
imageProvider: AssetImage(imagePath), // 使用 PhotoView 来显示图片
backgroundDecoration: BoxDecoration(
color: Colors.white, // 设置背景颜色为白色
),
),
),
);
}
}