2 changed files with 130 additions and 0 deletions
@ -0,0 +1,129 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
import '../controllers/agent_controller.dart'; |
||||
|
|
||||
|
//导航卡片 |
||||
|
Widget navigationCard( |
||||
|
BuildContext context, { |
||||
|
required String start, |
||||
|
required String end, |
||||
|
required String destination, |
||||
|
required List<Map<String, dynamic>> modes, |
||||
|
Map<String, dynamic>? navigation, |
||||
|
double height = 300, |
||||
|
}) { |
||||
|
int currentIndex = 0; |
||||
|
final controller = Get.find<AgentController>(); // 获取控制器 |
||||
|
return Container( |
||||
|
height: height, |
||||
|
decoration: BoxDecoration( |
||||
|
borderRadius: BorderRadius.circular(16), |
||||
|
color: Colors.white, |
||||
|
boxShadow: const [ |
||||
|
BoxShadow( |
||||
|
blurRadius: 8, |
||||
|
color: Colors.black12, |
||||
|
offset: Offset(0, 4), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
child: StatefulBuilder( |
||||
|
builder: (context, setInnerState) { |
||||
|
return Column( |
||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||
|
children: [ |
||||
|
// 路线图片 |
||||
|
ClipRRect( |
||||
|
borderRadius: |
||||
|
const BorderRadius.vertical(top: Radius.circular(16)), |
||||
|
child: AnimatedSwitcher( |
||||
|
duration: const Duration(milliseconds: 300), |
||||
|
child: Image.network( |
||||
|
modes[currentIndex]["image"] as String, |
||||
|
key: ValueKey<String>(modes[currentIndex]["ntype"] as String), |
||||
|
height: 160, |
||||
|
width: double.infinity, |
||||
|
fit: BoxFit.cover, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
|
||||
|
// 导航方式切换按钮 |
||||
|
Padding( |
||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4), |
||||
|
child: Row( |
||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
||||
|
children: List.generate(modes.length, (index) { |
||||
|
final isSelected = index == currentIndex; |
||||
|
return GestureDetector( |
||||
|
onTap: modes[index]['enable'] as bool |
||||
|
? () { |
||||
|
setInnerState(() => currentIndex = index); |
||||
|
} |
||||
|
: null, |
||||
|
child: SizedBox( |
||||
|
width: 50, |
||||
|
child: Text( |
||||
|
(modes[index]["ntype"] as String).tr, |
||||
|
textAlign: TextAlign.center, |
||||
|
style: TextStyle( |
||||
|
color: modes[index]['enable'] |
||||
|
? isSelected |
||||
|
? Colors.blue |
||||
|
: Colors.black87 |
||||
|
: Colors.grey, |
||||
|
fontSize: 12, |
||||
|
fontWeight: FontWeight.w500, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
}), |
||||
|
), |
||||
|
), |
||||
|
|
||||
|
// 距离和耗时 |
||||
|
Padding( |
||||
|
padding: const EdgeInsets.symmetric(horizontal: 8), |
||||
|
child: Row( |
||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
|
children: [ |
||||
|
Column( |
||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||
|
children: [ |
||||
|
Text('$destination', |
||||
|
style: const TextStyle( |
||||
|
fontSize: 12, color: Colors.black)), |
||||
|
Text( |
||||
|
'${formatDistance(modes[currentIndex]["distance"])}-约${formatDuration(modes[currentIndex]["duration"])}', |
||||
|
style: const TextStyle( |
||||
|
fontSize: 15, color: Colors.blue)), |
||||
|
if (navigation != null) |
||||
|
Text( |
||||
|
"导航中... ${navigation["distanceText"]}进入${navigation["nextRoad"]}", |
||||
|
style: TextStyle( |
||||
|
fontSize: 12, |
||||
|
color: |
||||
|
const Color.fromARGB(255, 164, 164, 164))) |
||||
|
], |
||||
|
), |
||||
|
CircleAvatar( |
||||
|
backgroundColor: Colors.blue, |
||||
|
radius: 18, |
||||
|
child: IconButton( |
||||
|
icon: const Icon(Icons.turn_left, |
||||
|
color: Colors.white, size: 20), |
||||
|
onPressed: () { |
||||
|
controller.openNavigation(start, end, ""); |
||||
|
}, |
||||
|
), |
||||
|
) |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
); |
||||
|
}, |
||||
|
), |
||||
|
); |
||||
|
} |
||||
Loading…
Reference in new issue