diff --git a/lib/modules/agent/views/message_bubble.dart b/lib/modules/agent/views/message_bubble.dart index ba2d33ff8..589b18b4a 100644 --- a/lib/modules/agent/views/message_bubble.dart +++ b/lib/modules/agent/views/message_bubble.dart @@ -1,4 +1,5 @@ import 'package:common_utils/common_utils.dart'; +import 'package:deep_voice/modules/agent/views/message_bubble_navigation.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; @@ -281,6 +282,11 @@ class MessageBubble extends GetView { rawList.map((e) => Map.from(e)).toList(); // 旅游 return _buildTravelContent(context, travellist); + } else if (meta!.keys.contains('card_navigation')) { + final rawList = meta!['card_navigation']['items'] as List; + final list = rawList.map((e) => Map.from(e)).toList(); + // 导航 + return navigationCard(context, modes: list); } // if (message.contains('播放列表') || message.contains('音乐')) { diff --git a/lib/modules/agent/views/message_bubble_navigation.dart b/lib/modules/agent/views/message_bubble_navigation.dart new file mode 100644 index 000000000..8ee1cd4bd --- /dev/null +++ b/lib/modules/agent/views/message_bubble_navigation.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; + +/// A widget that displays a navigation card with different modes of transportation. +Widget navigationCard( + BuildContext context, { + required List> modes, + double height = 260, +}) { + int currentIndex = 0; + + 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( + 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(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: () { + setInnerState(() => currentIndex = index); + }, + child: SizedBox( + width: 50, + child: Text( + modes[index]["ntype"] as String, + style: TextStyle( + color: isSelected ? Colors.blue : Colors.black87, + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ), + ), + ); + }), + ), + ), + + // 距离和耗时 + Padding( + padding: const EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('距离:${modes[currentIndex]["distance"]}', + style: const TextStyle(fontSize: 12, color: Colors.blue)), + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, // 👈 圆形背景 + color: Colors.blue, + ), + child: Icon(Icons.turn_left, + color: Colors.white, // 👈 圆形图标 + size: 20), + ) + ], + ), + ), + ], + ); + }, + ), + ); +}