148 lines
5.3 KiB
Dart
148 lines
5.3 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: LayoutBuilder(builder: (context, constraints) {
|
||
|
// 间距:你可以根据设计随意调整
|
||
|
const double horizontalGap = 20;
|
||
|
const double verticalGap = 5;
|
||
|
|
||
|
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] : '';
|
||
|
|
||
|
// 测量文字宽度
|
||
|
final leftPainter = TextPainter(
|
||
|
text: TextSpan(text: left, style: HhTextStyleUtils.secondaryTitleStyle),
|
||
|
maxLines: 1,
|
||
|
textDirection: TextDirection.ltr,
|
||
|
)..layout();
|
||
|
final rightPainter = TextPainter(
|
||
|
text: TextSpan(text: right, style: HhTextStyleUtils.secondaryTitleStyle),
|
||
|
maxLines: 1,
|
||
|
textDirection: TextDirection.ltr,
|
||
|
)..layout();
|
||
|
|
||
|
final canFitOneLine = right.isNotEmpty &&
|
||
|
(leftPainter.width + horizontalGap + rightPainter.width)
|
||
|
<= constraints.maxWidth;
|
||
|
|
||
|
if (right.isNotEmpty && canFitOneLine) {
|
||
|
// 同行显示,左右对齐
|
||
|
rows.add(Padding(
|
||
|
padding: EdgeInsets.only(bottom: verticalGap),
|
||
|
child: Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
|
children: [
|
||
|
_DetailText(left),
|
||
|
_DetailText(right),
|
||
|
],
|
||
|
),
|
||
|
));
|
||
|
} else {
|
||
|
// 拆为两行
|
||
|
rows.add(Padding(
|
||
|
padding: EdgeInsets.only(bottom: verticalGap),
|
||
|
child: Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||
|
children: [
|
||
|
// 上行:左对齐
|
||
|
_DetailText(left),
|
||
|
if (right.isNotEmpty)
|
||
|
// 下行:右对齐
|
||
|
Align(
|
||
|
alignment: Alignment.centerRight,
|
||
|
child: _DetailText(right),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Column(children: rows);
|
||
|
}),
|
||
|
),
|
||
|
|
||
|
// — 底部标签区 —
|
||
|
if (showBottomTags && bottomTags.isNotEmpty)
|
||
|
Padding(
|
||
|
padding: const EdgeInsets.only(left: 15, right: 15, bottom: 15),
|
||
|
child: Wrap(spacing: 5, runSpacing: 5, children: bottomTags),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Detail 文本封装:
|
||
|
/// 默认一行不换行;若超出则让整个组件撑宽,由外层判断拆行。
|
||
|
class _DetailText extends StatelessWidget {
|
||
|
final String text;
|
||
|
const _DetailText(this.text, {Key? key}) : super(key: key);
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Text(
|
||
|
text,
|
||
|
style: HhTextStyleUtils.secondaryTitleStyle,
|
||
|
softWrap: false,
|
||
|
overflow: TextOverflow.visible,
|
||
|
);
|
||
|
}
|
||
|
}
|