Files
flutterApp/lib/features/home/presentation/widgets/BottomDirectionLine.dart

171 lines
5.7 KiB
Dart
Raw Normal View History

2026-02-25 20:00:33 +08:00
import 'package:flutter/material.dart';
2026-02-26 09:17:14 +08:00
class RouteDirectionPanel extends StatefulWidget {
// 重命名为Panel更符合组件语义
2026-02-25 20:00:33 +08:00
// 接收外部传入的初始值
final bool initialOptimalHeading;
final double initialDirection;
// 新增:回调函数 - 关闭面板/返回设置结果
final ValueChanged<Map<String, dynamic>>? onConfirm;
final VoidCallback? onCancel;
const RouteDirectionPanel({
super.key,
this.initialOptimalHeading = true, // 默认开启最优航向
2026-02-26 09:17:14 +08:00
this.initialDirection = 0.0, // 默认方向0度
2026-02-25 20:00:33 +08:00
this.onConfirm,
this.onCancel,
});
@override
State<RouteDirectionPanel> createState() => _RouteDirectionPanelState();
}
class _RouteDirectionPanelState extends State<RouteDirectionPanel> {
late bool _optimalHeading;
late double _direction; // 0-360度范围
@override
void initState() {
super.initState();
_optimalHeading = widget.initialOptimalHeading;
_direction = widget.initialDirection.clamp(0, 360); // 限制在0-360度
}
@override
Widget build(BuildContext context) {
// 纯面板结构:无Scaffold,仅Container包裹核心UI
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 8)],
),
padding: const EdgeInsets.all(16),
constraints: const BoxConstraints(minHeight: 300), // 最小高度保证UI完整
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 顶部标题栏 + 返回按钮
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 取消/返回按钮
GestureDetector(
onTap: () {
widget.onCancel?.call(); // 触发取消回调
},
child: const Icon(
Icons.arrow_back_ios,
color: Colors.black87,
size: 20,
),
),
const Text(
'航线方向',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
const SizedBox(width: 24), // 占位保持标题居中
],
),
2026-02-26 10:44:56 +08:00
const SizedBox(height: 10),
2026-02-26 09:17:14 +08:00
//const Divider(height: 1, color: Colors.grey),
//const SizedBox(height: 20),
2026-02-25 20:00:33 +08:00
// 最优航向开关
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'最优航向',
style: TextStyle(fontSize: 16, color: Colors.black87),
),
Switch(
value: _optimalHeading,
activeColor: const Color(0xFF00C853),
onChanged: (bool value) {
setState(() {
_optimalHeading = value;
});
},
),
],
),
2026-02-26 10:44:56 +08:00
const SizedBox(height: 10),
2026-02-25 20:00:33 +08:00
// 航线方向滑块
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'航线方向',
style: TextStyle(fontSize: 16, color: Colors.black87),
),
Text(
'${_direction.toStringAsFixed(0)}°',
style: TextStyle(
fontSize: 16,
color: _optimalHeading ? Colors.grey : Colors.black87,
fontWeight: FontWeight.w500,
),
),
],
),
2026-02-26 10:44:56 +08:00
const SizedBox(height: 10),
2026-02-25 20:00:33 +08:00
Slider(
value: _direction,
min: 0,
max: 360,
divisions: 36,
label: '${_direction.toStringAsFixed(0)}°',
activeColor: const Color(0xFF00C853),
inactiveColor: Colors.grey[300],
onChanged: _optimalHeading
? null
: (double value) {
setState(() {
_direction = value;
});
},
),
],
),
2026-02-26 10:44:56 +08:00
const SizedBox(height: 10),
2026-02-25 20:00:33 +08:00
// 确认按钮
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
// 触发确认回调,传递设置结果
widget.onConfirm?.call({
'optimalHeading': _optimalHeading,
'direction': _direction,
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF00C853),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text('确认'),
),
),
],
),
),
);
}
}