Browse Source
将旅游卡片相关逻辑从 `message_bubble.dart` 中提取到独立的 `travel_card.dart` 文件中,提高代码可维护性。同时优化了代码格式,包括缩进、空格和换行,提升代码可读性。weicu
3 changed files with 241 additions and 238 deletions
@ -0,0 +1,211 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
|
||||
|
/// 构建旅游内容卡片 |
||||
|
Widget buildTravelContent( |
||||
|
BuildContext context, List<Map<String, dynamic>> travellist) { |
||||
|
return Column( |
||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||
|
children: [ |
||||
|
const Text( |
||||
|
'以下是一些推搜索结果:', |
||||
|
style: TextStyle( |
||||
|
color: Colors.black87, |
||||
|
fontSize: 14, |
||||
|
height: 1.4, |
||||
|
fontWeight: FontWeight.w400, |
||||
|
), |
||||
|
), |
||||
|
const SizedBox(height: 12), |
||||
|
Container( |
||||
|
padding: const EdgeInsets.all(12), |
||||
|
decoration: BoxDecoration( |
||||
|
color: Colors.white, |
||||
|
borderRadius: BorderRadius.circular(12), |
||||
|
boxShadow: [ |
||||
|
BoxShadow( |
||||
|
color: Colors.black.withOpacity(0.03), |
||||
|
blurRadius: 3, |
||||
|
spreadRadius: 1, |
||||
|
offset: const Offset(0, 1), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
child: Column( |
||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||
|
children: [ |
||||
|
// Row( |
||||
|
// children: [ |
||||
|
// Icon( |
||||
|
// Icons.place, |
||||
|
// size: 16, |
||||
|
// color: Color(0xFFE11D48), |
||||
|
// ), |
||||
|
// const SizedBox(width: 6), |
||||
|
// Text( |
||||
|
// '热门景点 · 东京', |
||||
|
// style: TextStyle( |
||||
|
// fontSize: 13, |
||||
|
// fontWeight: FontWeight.w600, |
||||
|
// color: Colors.grey[700], |
||||
|
// ), |
||||
|
// ), |
||||
|
// ], |
||||
|
// ), |
||||
|
// const SizedBox(height: 10), |
||||
|
|
||||
|
// 动态生成音乐条目 |
||||
|
...travellist.asMap().entries.map((entry) { |
||||
|
final index = entry.key; |
||||
|
final item = entry.value; |
||||
|
final name = item["name"] ?? "未知歌曲"; //名字 |
||||
|
final addr = item["addr"] ?? ""; //地址 |
||||
|
final tag = item["tag"] ?? "未知歌手"; //标签 |
||||
|
final rating = item["rating"] ?? ""; //评分 |
||||
|
final distance = item["distance"] ?? ""; //距离 |
||||
|
final images = item["images"] ?? []; // 图片列表 |
||||
|
return Column( |
||||
|
children: [ |
||||
|
buildLocationItem( |
||||
|
context, |
||||
|
name, |
||||
|
addr, |
||||
|
), |
||||
|
if (index != travellist.length - 1) |
||||
|
Divider(height: 1, thickness: 1, color: Colors.grey[100]), |
||||
|
], |
||||
|
); |
||||
|
}).toList(), |
||||
|
// // 景点列表 |
||||
|
// _buildLocationItem('东京塔', '标志性建筑,可俯瞰东京全景', context), |
||||
|
// Divider(height: 1, thickness: 1, color: Colors.grey[100]), |
||||
|
// _buildLocationItem('涩谷十字路口', '世界上最繁忙的十字路口之一', context), |
||||
|
// Divider(height: 1, thickness: 1, color: Colors.grey[100]), |
||||
|
// _buildLocationItem('浅草寺', '东京最古老的寺庙', context), |
||||
|
|
||||
|
const SizedBox(height: 8), |
||||
|
Center( |
||||
|
child: TextButton( |
||||
|
onPressed: () {}, |
||||
|
style: TextButton.styleFrom( |
||||
|
minimumSize: Size.zero, |
||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), |
||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap, |
||||
|
), |
||||
|
child: Text( |
||||
|
'查看更多景点', |
||||
|
style: TextStyle( |
||||
|
fontSize: 12, |
||||
|
color: Theme.of(context).primaryColor, |
||||
|
fontWeight: FontWeight.w500, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
const SizedBox(height: 10), |
||||
|
Row( |
||||
|
mainAxisSize: MainAxisSize.min, |
||||
|
children: [ |
||||
|
Expanded( |
||||
|
child: OutlinedButton.icon( |
||||
|
onPressed: () {}, |
||||
|
icon: Icon(Icons.map, size: 16), |
||||
|
label: Text('查看地图'), |
||||
|
style: OutlinedButton.styleFrom( |
||||
|
foregroundColor: Theme.of(context).primaryColor, |
||||
|
side: BorderSide( |
||||
|
color: Theme.of(context).primaryColor.withOpacity(0.5)), |
||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4), |
||||
|
shape: RoundedRectangleBorder( |
||||
|
borderRadius: BorderRadius.circular(16), |
||||
|
), |
||||
|
textStyle: TextStyle(fontSize: 12), |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
SizedBox(width: 8), |
||||
|
Expanded( |
||||
|
child: OutlinedButton.icon( |
||||
|
onPressed: () {}, |
||||
|
icon: Icon(Icons.bookmark_border, size: 16), |
||||
|
label: Text('保存到收藏'), |
||||
|
style: OutlinedButton.styleFrom( |
||||
|
foregroundColor: Colors.grey[700], |
||||
|
side: BorderSide(color: Colors.grey[400]!), |
||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4), |
||||
|
shape: RoundedRectangleBorder( |
||||
|
borderRadius: BorderRadius.circular(16), |
||||
|
), |
||||
|
textStyle: TextStyle(fontSize: 12), |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
], |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 构建地点项目 |
||||
|
Widget buildLocationItem( |
||||
|
BuildContext context, String name, String description) { |
||||
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
||||
|
|
||||
|
return Padding( |
||||
|
padding: const EdgeInsets.symmetric(vertical: 8), |
||||
|
child: Row( |
||||
|
children: [ |
||||
|
Container( |
||||
|
width: 38, |
||||
|
height: 38, |
||||
|
decoration: BoxDecoration( |
||||
|
color: isDarkMode ? Color(0xFF1A365D) : Colors.blue[50], |
||||
|
borderRadius: BorderRadius.circular(8), |
||||
|
), |
||||
|
child: Icon( |
||||
|
Icons.place, |
||||
|
size: 18, |
||||
|
color: Color(0xFFE11D48), |
||||
|
), |
||||
|
), |
||||
|
const SizedBox(width: 12), |
||||
|
Expanded( |
||||
|
child: Column( |
||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||
|
children: [ |
||||
|
Text( |
||||
|
name, |
||||
|
style: TextStyle( |
||||
|
fontSize: 13, |
||||
|
fontWeight: FontWeight.w500, |
||||
|
color: isDarkMode |
||||
|
? Colors.white.withOpacity(0.9) |
||||
|
: Colors.grey[800], |
||||
|
), |
||||
|
overflow: TextOverflow.ellipsis, |
||||
|
), |
||||
|
SizedBox(height: 2), |
||||
|
Text( |
||||
|
description, |
||||
|
style: TextStyle( |
||||
|
fontSize: 12, |
||||
|
color: isDarkMode ? Colors.grey[400] : Colors.grey[600], |
||||
|
), |
||||
|
overflow: TextOverflow.ellipsis, |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
IconButton( |
||||
|
onPressed: () {}, |
||||
|
icon: Icon(Icons.arrow_forward, color: Colors.grey[400]), |
||||
|
padding: EdgeInsets.zero, |
||||
|
constraints: BoxConstraints(), |
||||
|
iconSize: 20, |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
); |
||||
|
} |
||||
Loading…
Reference in new issue