156 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Dart
		
	
	
| import 'package:flutter/material.dart';
 | |
| import '../tools/tools.dart';
 | |
| 
 | |
| /// 通用列表卡片组件:
 | |
| /// - 两两为一组,固定左右布局,平均分配宽度
 | |
| /// - 左侧文字左对齐,右侧文字右对齐
 | |
| /// - 文字过多时各自自动换行
 | |
| /// - 如果一行只有一个元素,靠左显示
 | |
| 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),
 | |
| 
 | |
|             // — 详情区:固定左右布局 —
 | |
|             Padding(
 | |
|               padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
 | |
|               child: Column(
 | |
|                 children: _buildDetailRows(),
 | |
|               ),
 | |
|             ),
 | |
| 
 | |
|             // — 底部标签区 —
 | |
|             if (showBottomTags && bottomTags.isNotEmpty)
 | |
|               Padding(
 | |
|                 padding: const EdgeInsets.only(left: 15, right: 15, bottom: 15),
 | |
|                 child: Wrap(spacing: 5, runSpacing: 5, children: bottomTags),
 | |
|               ),
 | |
|           ],
 | |
|         ),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   // 构建详情行
 | |
|   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),
 | |
|         ),
 | |
|       ],
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /// Detail 文本封装:支持自动换行和指定的对齐方式
 | |
| class _DetailText extends StatelessWidget {
 | |
|   final String text;
 | |
|   final TextAlign textAlign;
 | |
| 
 | |
|   const _DetailText(this.text, {
 | |
|     Key? key,
 | |
|     required this.textAlign,
 | |
|   }) : super(key: key);
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return Text(
 | |
|       text,
 | |
|       style: HhTextStyleUtils.secondaryTitleStyle,
 | |
|       softWrap: true, // 允许换行
 | |
|       textAlign: textAlign, // 使用指定的对齐方式
 | |
|     );
 | |
|   }
 | |
| } |