| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | import '../tools/tools.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// 通用列表卡片组件:
 | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  | /// - 两两为一组,固定左右布局,平均分配宽度
 | 
					
						
							|  |  |  | /// - 左侧文字左对齐,右侧文字右对齐
 | 
					
						
							|  |  |  | /// - 文字过多时各自自动换行
 | 
					
						
							|  |  |  | /// - 如果一行只有一个元素,靠左显示
 | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  | class DannerRepainItem extends StatelessWidget { | 
					
						
							|  |  |  |   final String title; | 
					
						
							|  |  |  |   final List<String> details; | 
					
						
							|  |  |  |   final bool showBottomTags; | 
					
						
							|  |  |  |   final List<Widget> bottomTags; | 
					
						
							|  |  |  |   final bool showTitleIcon; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const DannerRepainItem({ | 
					
						
							|  |  |  |     Key? key, | 
					
						
							|  |  |  |     required this.title, | 
					
						
							|  |  |  |     required this.details, | 
					
						
							|  |  |  |     this.showBottomTags = false, | 
					
						
							|  |  |  |     this.showTitleIcon = true, | 
					
						
							|  |  |  |     this.bottomTags = const [], | 
					
						
							|  |  |  |   }) : super(key: key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     return Padding( | 
					
						
							|  |  |  |       padding: const EdgeInsets.only(left: 15, right: 15, bottom: 15), | 
					
						
							|  |  |  |       child: Container( | 
					
						
							|  |  |  |         decoration: const BoxDecoration( | 
					
						
							|  |  |  |           color: Colors.white, | 
					
						
							|  |  |  |           borderRadius: BorderRadius.all(Radius.circular(5)), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         child: Column( | 
					
						
							|  |  |  |           crossAxisAlignment: CrossAxisAlignment.stretch, | 
					
						
							|  |  |  |           children: [ | 
					
						
							|  |  |  |             // — 标题行 —
 | 
					
						
							|  |  |  |             Padding( | 
					
						
							|  |  |  |               padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), | 
					
						
							|  |  |  |               child: Row( | 
					
						
							|  |  |  |                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | 
					
						
							|  |  |  |                 children: [ | 
					
						
							|  |  |  |                   Row(children: [ | 
					
						
							|  |  |  |                     if (showTitleIcon) | 
					
						
							|  |  |  |                       const Icon(Icons.star_rate_sharp, color: Colors.green, size: 18), | 
					
						
							|  |  |  |                     SizedBox(width: showTitleIcon ? 5 : 0), | 
					
						
							|  |  |  |                     Text(title, style: const TextStyle(fontSize: 14)), | 
					
						
							|  |  |  |                   ]), | 
					
						
							|  |  |  |                   const Icon(Icons.arrow_forward_ios_rounded, color: Colors.grey, size: 15), | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             const Divider(height: 1), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  |             // — 详情区:固定左右布局 —
 | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |             Padding( | 
					
						
							|  |  |  |               padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  |               child: Column( | 
					
						
							|  |  |  |                 children: _buildDetailRows(), | 
					
						
							|  |  |  |               ), | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |             ), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // — 底部标签区 —
 | 
					
						
							|  |  |  |             if (showBottomTags && bottomTags.isNotEmpty) | 
					
						
							|  |  |  |               Padding( | 
					
						
							|  |  |  |                 padding: const EdgeInsets.only(left: 15, right: 15, bottom: 15), | 
					
						
							|  |  |  |                 child: Wrap(spacing: 5, runSpacing: 5, children: bottomTags), | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // 构建详情行
 | 
					
						
							|  |  |  |   List<Widget> _buildDetailRows() { | 
					
						
							|  |  |  |     List<Widget> rows = []; | 
					
						
							|  |  |  |     for (int i = 0; i < details.length; i += 2) { | 
					
						
							|  |  |  |       final left = details[i]; | 
					
						
							|  |  |  |       final right = (i + 1 < details.length) ? details[i + 1] : ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       rows.add( | 
					
						
							|  |  |  |         Padding( | 
					
						
							|  |  |  |           padding: const EdgeInsets.only(bottom: 8), | 
					
						
							|  |  |  |           child: _DetailRow(left: left, right: right), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return rows; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// 详情行组件:固定左右布局,平均分配宽度,各自换行
 | 
					
						
							|  |  |  | /// 如果只有左侧文本,则靠左显示
 | 
					
						
							|  |  |  | class _DetailRow extends StatelessWidget { | 
					
						
							|  |  |  |   final String left; | 
					
						
							|  |  |  |   final String right; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const _DetailRow({ | 
					
						
							|  |  |  |     Key? key, | 
					
						
							|  |  |  |     required this.left, | 
					
						
							|  |  |  |     required this.right, | 
					
						
							|  |  |  |   }) : super(key: key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     // 如果右侧文本为空,只显示左侧文本,靠左显示
 | 
					
						
							|  |  |  |     if (right.isEmpty) { | 
					
						
							|  |  |  |       return Align( | 
					
						
							|  |  |  |         alignment: Alignment.centerLeft, | 
					
						
							|  |  |  |         child: _DetailText(left, textAlign: TextAlign.left), | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Row( | 
					
						
							|  |  |  |       crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |       children: [ | 
					
						
							|  |  |  |         // 左侧文本 - 占50%宽度
 | 
					
						
							|  |  |  |         Expanded( | 
					
						
							|  |  |  |           flex: 1, | 
					
						
							|  |  |  |           child: _DetailText(left, textAlign: TextAlign.left), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 中间间距
 | 
					
						
							|  |  |  |         const SizedBox(width: 10), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 右侧文本 - 占50%宽度
 | 
					
						
							|  |  |  |         Expanded( | 
					
						
							|  |  |  |           flex: 1, | 
					
						
							|  |  |  |           child: _DetailText(right, textAlign: TextAlign.right), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  | /// Detail 文本封装:支持自动换行和指定的对齐方式
 | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  | class _DetailText extends StatelessWidget { | 
					
						
							|  |  |  |   final String text; | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  |   final TextAlign textAlign; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const _DetailText(this.text, { | 
					
						
							|  |  |  |     Key? key, | 
					
						
							|  |  |  |     required this.textAlign, | 
					
						
							|  |  |  |   }) : super(key: key); | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     return Text( | 
					
						
							|  |  |  |       text, | 
					
						
							|  |  |  |       style: HhTextStyleUtils.secondaryTitleStyle, | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  |       softWrap: true, // 允许换行
 | 
					
						
							|  |  |  |       textAlign: textAlign, // 使用指定的对齐方式
 | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-09-19 18:01:23 +08:00
										 |  |  | } |