Files
flutterApp/lib/features/home/presentation/widgets/BottomDirectionLine.dart
2026-02-26 10:44:56 +08:00

171 lines
5.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
class RouteDirectionPanel extends StatefulWidget {
// 重命名为Panel更符合组件语义
// 接收外部传入的初始值
final bool initialOptimalHeading;
final double initialDirection;
// 新增:回调函数 - 关闭面板/返回设置结果
final ValueChanged<Map<String, dynamic>>? onConfirm;
final VoidCallback? onCancel;
const RouteDirectionPanel({
super.key,
this.initialOptimalHeading = true, // 默认开启最优航向
this.initialDirection = 0.0, // 默认方向0度
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), // 占位保持标题居中
],
),
const SizedBox(height: 10),
//const Divider(height: 1, color: Colors.grey),
//const SizedBox(height: 20),
// 最优航向开关
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;
});
},
),
],
),
const SizedBox(height: 10),
// 航线方向滑块
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,
),
),
],
),
const SizedBox(height: 10),
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;
});
},
),
],
),
const SizedBox(height: 10),
// 确认按钮
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('确认'),
),
),
],
),
),
);
}
}