mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-08 17:40:28 +00:00
temp
This commit is contained in:
1 parent
2ab5a4bb53
commit
8835c2855a
11 files changed
+851
-47
No files matched your search
@@ -1,60 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GradientButton extends StatelessWidget {
|
||||
final String text;
|
||||
final VoidCallback onPressed;
|
||||
final IconData? icon; // 添加可选图标参数
|
||||
|
||||
const GradientButton({
|
||||
super.key,
|
||||
required this.text,
|
||||
required this.onPressed,
|
||||
this.icon,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 120,
|
||||
height: 40,
|
||||
child: ElevatedButton(
|
||||
onPressed: onPressed,
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(143),
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
child: Ink(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Color(0xFF3ACBBE), Color(0xFF2CDB90)],
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.circular(143)),
|
||||
),
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (icon != null) Icon(icon, size: 16.0, color: Colors.white),
|
||||
if (icon != null) const SizedBox(width: 4.0), // 图标和文本之间的间距
|
||||
Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFFFFFFFE),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'gradient_button.dart';
|
||||
import '../../../components/gp_gradient_button.dart';
|
||||
import '../../../components/gp_outline_button.dart';
|
||||
import '../../../components/gp_icon_button.dart';
|
||||
import '../widgets/task_item.dart';
|
||||
import 'task_tabs.dart';
|
||||
|
||||
class TaskScreen extends StatefulWidget {
|
||||
@@ -32,7 +35,7 @@ class _TaskScreenState extends State<TaskScreen> {
|
||||
padding: const EdgeInsets.only(left: 16.0, top: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
GradientButton(
|
||||
GpGradientButton(
|
||||
text: '创建任务',
|
||||
icon: Icons.add, // 添加加号图标
|
||||
onPressed: () {
|
||||
@@ -49,7 +52,37 @@ class _TaskScreenState extends State<TaskScreen> {
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(height: 16),
|
||||
// 操作按钮列表
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 24.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
GpOutlineButton(
|
||||
icon: 'assets/icons/pause.png',
|
||||
onTap: () {
|
||||
// 处理开始按钮点击事件
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
GpOutlineButton(
|
||||
icon: 'assets/icons/pause.png',
|
||||
onTap: () {
|
||||
// 处理暂停按钮点击事件
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
GpOutlineButton(
|
||||
icon: 'assets/icons/pause.png',
|
||||
onTap: () {
|
||||
// 处理删除按钮点击事件
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Expanded(child: _buildTaskList(_selectedTabIndex)),
|
||||
],
|
||||
),
|
||||
@@ -60,16 +93,126 @@ class _TaskScreenState extends State<TaskScreen> {
|
||||
// 根据选中的标签页显示不同的任务列表
|
||||
switch (tabIndex) {
|
||||
case 0:
|
||||
return const Center(
|
||||
child: Text('下载中的任务列表', style: TextStyle(color: Colors.white)),
|
||||
return ListView.separated(
|
||||
itemCount: 3, // 示例显示3个任务项
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 12),
|
||||
itemBuilder:
|
||||
(context, index) => TaskItem(
|
||||
icon: Icons.download, // 添加下载图标
|
||||
taskName: '下载任务 ${index + 1}', // 添加任务名称
|
||||
progress: (index + 1) * 0.25, // 添加进度值 (0.25, 0.5, 0.75)
|
||||
fileSizeText:
|
||||
'${(2.1 + index * 0.1).toStringAsFixed(1)}MB/2.4MB', // 示例文件大小
|
||||
bottomRightIcon: Icons.speed, // 添加速度图标
|
||||
bottomRightGradientText:
|
||||
'${(1.5 + index * 0.3).toStringAsFixed(1)}MB/s', // 下载速度
|
||||
bottomRightStatusText: '下载中', // 状态文本
|
||||
actionButtons: [
|
||||
GpIconButton(
|
||||
icon: Icons.pause,
|
||||
onTap: () => print('暂停任务 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.delete,
|
||||
onTap: () => print('删除任务 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.folder_open,
|
||||
onTap: () => print('打开所在位置 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.info,
|
||||
onTap: () => print('查看信息 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.more_vert,
|
||||
onTap: () => print('更多操作 $index'),
|
||||
),
|
||||
],
|
||||
onTap: () {
|
||||
print('任务项 $index 被点击');
|
||||
},
|
||||
),
|
||||
);
|
||||
case 1:
|
||||
return const Center(
|
||||
child: Text('已完成的任务列表', style: TextStyle(color: Colors.white)),
|
||||
return ListView.separated(
|
||||
itemCount: 2, // 示例显示2个任务项
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 12),
|
||||
itemBuilder:
|
||||
(context, index) => TaskItem(
|
||||
icon: Icons.check_circle, // 添加完成图标
|
||||
taskName: '已完成任务 ${index + 1}', // 添加任务名称
|
||||
progress: 1.0, // 已完成任务进度为100%
|
||||
fileSizeText: '2.4MB/2.4MB - 已完成', // 添加完成信息
|
||||
bottomRightIcon: Icons.check, // 添加完成图标
|
||||
bottomRightGradientText: '完成时间', // 完成时间文本
|
||||
bottomRightStatusText: '已完成', // 状态文本
|
||||
actionButtons: [
|
||||
GpIconButton(
|
||||
icon: Icons.pause,
|
||||
onTap: () => print('暂停任务 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.delete,
|
||||
onTap: () => print('删除任务 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.folder_open,
|
||||
onTap: () => print('打开所在位置 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.info,
|
||||
onTap: () => print('查看信息 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.more_vert,
|
||||
onTap: () => print('更多操作 $index'),
|
||||
),
|
||||
],
|
||||
onTap: () {
|
||||
print('已完成任务项 $index 被点击');
|
||||
},
|
||||
),
|
||||
);
|
||||
case 2:
|
||||
return const Center(
|
||||
child: Text('失败的任务列表', style: TextStyle(color: Colors.white)),
|
||||
return ListView.separated(
|
||||
itemCount: 1, // 示例显示1个任务项
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 12),
|
||||
itemBuilder:
|
||||
(context, index) => TaskItem(
|
||||
icon: Icons.error, // 添加错误图标
|
||||
taskName: '失败任务 ${index + 1}', // 添加任务名称
|
||||
progress: 0.3, // 失败任务的部分进度
|
||||
fileSizeText: '1.2MB/4.0MB - 任务失败', // 添加失败信息
|
||||
bottomRightIcon: Icons.error_outline, // 添加错误图标
|
||||
bottomRightGradientText: '重试', // 重试文本
|
||||
bottomRightStatusText: '失败', // 状态文本
|
||||
actionButtons: [
|
||||
GpIconButton(
|
||||
icon: Icons.pause,
|
||||
onTap: () => print('暂停任务 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.delete,
|
||||
onTap: () => print('删除任务 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.folder_open,
|
||||
onTap: () => print('打开所在位置 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.info,
|
||||
onTap: () => print('查看信息 $index'),
|
||||
),
|
||||
GpIconButton(
|
||||
icon: Icons.more_vert,
|
||||
onTap: () => print('更多操作 $index'),
|
||||
),
|
||||
],
|
||||
onTap: () {
|
||||
print('失败任务项 $index 被点击');
|
||||
},
|
||||
),
|
||||
);
|
||||
default:
|
||||
return Container();
|
||||
|
||||
@@ -0,0 +1,491 @@
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// TaskItem - 任务项组件
|
||||
///
|
||||
/// 一个带有毛玻璃效果和渐变边框的任务项容器,宽度自适应父组件
|
||||
class TaskItem extends StatelessWidget {
|
||||
/// 左侧图标
|
||||
final dynamic icon;
|
||||
|
||||
/// 任务名称
|
||||
final String? taskName;
|
||||
|
||||
/// 进度值 (0.0 - 1.0)
|
||||
final double? progress;
|
||||
|
||||
/// 右上角操作按钮列表
|
||||
final List<Widget>? actionButtons;
|
||||
|
||||
/// 容器高度,默认106px
|
||||
final double height;
|
||||
|
||||
/// 圆角大小,默认8px
|
||||
final double borderRadius;
|
||||
|
||||
/// 点击回调
|
||||
final VoidCallback? onTap;
|
||||
|
||||
/// 文件大小文本(如2.1MB/2.4MB)
|
||||
final String? fileSizeText;
|
||||
|
||||
/// 右下角图标
|
||||
final IconData? bottomRightIcon;
|
||||
|
||||
/// 右下角渐变文本
|
||||
final String? bottomRightGradientText;
|
||||
|
||||
/// 右下角状态文本
|
||||
final String? bottomRightStatusText;
|
||||
|
||||
const TaskItem({
|
||||
super.key,
|
||||
this.icon,
|
||||
this.taskName,
|
||||
this.progress,
|
||||
this.actionButtons,
|
||||
this.height = 106.0,
|
||||
this.borderRadius = 8.0,
|
||||
this.onTap,
|
||||
this.fileSizeText,
|
||||
this.bottomRightIcon,
|
||||
this.bottomRightGradientText,
|
||||
this.bottomRightStatusText,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
cursor:
|
||||
onTap != null ? SystemMouseCursors.click : SystemMouseCursors.basic,
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
height: height,
|
||||
child: Stack(
|
||||
children: [
|
||||
// Rectangle 82: 主容器 (最底层)
|
||||
Positioned.fill(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 24.0, sigmaY: 24.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
// 背景色:rgba(178, 231, 254, 0.08)
|
||||
color: const Color(0xFFB2E7FE).withOpacity(0.08),
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
border: Border.all(
|
||||
width: 0.5,
|
||||
color: Colors.transparent,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
// 渐变边框效果
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
stops: [0.17, 0.92],
|
||||
colors: [
|
||||
Colors.transparent,
|
||||
Color(0x29FFFFFF), // rgba(255, 255, 255, 0.16)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 蒙版组 (中间层) - 简化测试
|
||||
Positioned.fill(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Rectangle 80: 渐变模糊背景 - 只保留这个
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 7.23,
|
||||
child: ImageFiltered(
|
||||
imageFilter: ImageFilter.blur(
|
||||
sigmaX: 40.0,
|
||||
sigmaY: 40.0,
|
||||
),
|
||||
child: Container(
|
||||
height: 90.34,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.centerLeft, // 90deg = 从左到右
|
||||
end: Alignment.centerRight,
|
||||
stops: [0.0, 1.0],
|
||||
colors: [
|
||||
Color(0xFF2D3975), // #2D3975 at 0%
|
||||
Color(0xFF266682), // #266682 at 100%
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Rectangle 81: 纯色背景蒙版 - 图层样式穿透,所以注释掉
|
||||
// 设计稿中标明"图层样式穿透",意味着这层不影响最终视觉效果
|
||||
// Positioned(
|
||||
// left: 0,
|
||||
// right: 0,
|
||||
// top: 0,
|
||||
// child: Container(
|
||||
// height: height,
|
||||
// decoration: BoxDecoration(
|
||||
// color: const Color(0xFFB2E7FE),
|
||||
// borderRadius: BorderRadius.circular(borderRadius),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 内容层 (最上层)
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16.0), // 统一的16px内边距
|
||||
child: Row(
|
||||
children: [
|
||||
// 左侧图标区域
|
||||
if (icon != null)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
right: 2.0,
|
||||
), // 图标右边间隔2px
|
||||
child: _buildIcon(),
|
||||
),
|
||||
|
||||
// 右侧内容容器
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 任务名称区域 (与操作按钮在同一行)
|
||||
Row(
|
||||
children: [
|
||||
// 任务名称
|
||||
if (taskName != null)
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 22.0, // 设计稿高度22px
|
||||
child: Align(
|
||||
alignment:
|
||||
Alignment
|
||||
.bottomLeft, // align-items: flex-end
|
||||
child: Text(
|
||||
taskName!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16.0, // 16px
|
||||
fontWeight:
|
||||
FontWeight.bold, // bold
|
||||
height:
|
||||
22.0 /
|
||||
16.0, // line-height: 22px
|
||||
color: Color(
|
||||
0xFFFFFFFE,
|
||||
), // #FFFFFE
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 右侧操作按钮列表
|
||||
if (actionButtons != null &&
|
||||
actionButtons!.isNotEmpty)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: _buildActionButtons(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 进度条
|
||||
if (progress != null)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
top: 20.0,
|
||||
), // 距离名称下面20px
|
||||
child: _buildProgressBar(),
|
||||
),
|
||||
|
||||
// 文件大小文本和右下角元素行
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
top: 8.0,
|
||||
), // 距离进度条下面8px
|
||||
height: 16.0, // 直接指定高度为16px
|
||||
child: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center, // 垂直居中对齐
|
||||
children: [
|
||||
// 左侧文件大小文本
|
||||
if (fileSizeText != null &&
|
||||
fileSizeText!.isNotEmpty)
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
fileSizeText!,
|
||||
style: const TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(
|
||||
0xFFCCCCCC,
|
||||
), // #CCCCCC
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 右下角元素组
|
||||
_buildBottomRightElements(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建图标组件
|
||||
Widget _buildIcon() {
|
||||
if (icon == null) return const SizedBox.shrink();
|
||||
|
||||
// 如果是字符串,认为是资源路径
|
||||
if (icon is String) {
|
||||
return Image.asset(
|
||||
icon as String,
|
||||
width: 32.0,
|
||||
height: 32.0,
|
||||
fit: BoxFit.contain,
|
||||
);
|
||||
}
|
||||
|
||||
// 如果是IconData,使用Icon组件
|
||||
if (icon is IconData) {
|
||||
return Icon(icon as IconData, size: 32.0, color: Colors.white);
|
||||
}
|
||||
|
||||
// 如果是Widget,直接使用
|
||||
if (icon is Widget) {
|
||||
return SizedBox(width: 32.0, height: 32.0, child: icon as Widget);
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
/// 构建操作按钮列表
|
||||
List<Widget> _buildActionButtons() {
|
||||
if (actionButtons == null || actionButtons!.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
List<Widget> buttons = [];
|
||||
for (int i = 0; i < actionButtons!.length; i++) {
|
||||
// 添加按钮
|
||||
buttons.add(
|
||||
SizedBox(width: 20.0, height: 20.0, child: actionButtons![i]),
|
||||
);
|
||||
|
||||
// 添加间隔 (除了最后一个按钮)
|
||||
if (i < actionButtons!.length - 1) {
|
||||
buttons.add(const SizedBox(width: 16.0));
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
/// 构建进度条
|
||||
Widget _buildProgressBar() {
|
||||
if (progress == null) return const SizedBox.shrink();
|
||||
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
// 使用所有可用宽度,因为已经有统一的16px内边距
|
||||
final availableWidth = constraints.maxWidth;
|
||||
final progressWidth = availableWidth * progress!;
|
||||
|
||||
return SizedBox(
|
||||
height: 8.0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 底部背景条
|
||||
Container(
|
||||
width: availableWidth,
|
||||
height: 8.0,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEBEDF3), // #EBEDF3
|
||||
borderRadius: BorderRadius.circular(548.0), // 548px圆角
|
||||
),
|
||||
),
|
||||
|
||||
// 进度条
|
||||
Container(
|
||||
width: progressWidth,
|
||||
height: 8.0,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(143.0), // 143px圆角
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.centerLeft, // 90deg
|
||||
end: Alignment.centerRight,
|
||||
stops: [0.0, 0.44, 0.99],
|
||||
colors: [
|
||||
Color(0xC93ACBBE), // rgba(58, 203, 190, 0.79)
|
||||
Color(0xFF3ACBBE), // #3ACBBE at 44%
|
||||
Color(0xFF2CDB90), // #2CDB90 at 99%
|
||||
],
|
||||
),
|
||||
border: Border.all(width: 1.0, color: Colors.transparent),
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(143.0),
|
||||
// 渐变边框效果
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topCenter, // 180deg
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Color(0xFF39CBBC), // #39CBBC at 0%
|
||||
Color(0xFF2CDA92), // #2CDA92 at 100%
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(1.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(142.0),
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
stops: [0.0, 0.44, 0.99],
|
||||
colors: [
|
||||
Color(0xC93ACBBE), // rgba(58, 203, 190, 0.79)
|
||||
Color(0xFF3ACBBE), // #3ACBBE at 44%
|
||||
Color(0xFF2CDB90), // #2CDB90 at 99%
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建右下角元素组
|
||||
Widget _buildBottomRightElements() {
|
||||
// 如果没有任何右下角元素,返回空
|
||||
if (bottomRightIcon == null &&
|
||||
bottomRightGradientText == null &&
|
||||
bottomRightStatusText == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
List<Widget> children = [];
|
||||
|
||||
// 添加图标
|
||||
if (bottomRightIcon != null) {
|
||||
children.add(Icon(bottomRightIcon!, size: 16.0, color: Colors.white));
|
||||
}
|
||||
|
||||
// 添加渐变文本
|
||||
if (bottomRightGradientText != null &&
|
||||
bottomRightGradientText!.isNotEmpty) {
|
||||
if (children.isNotEmpty) {
|
||||
children.add(const SizedBox(width: 4.0)); // 间隔4px
|
||||
}
|
||||
|
||||
children.add(
|
||||
ShaderMask(
|
||||
shaderCallback:
|
||||
(bounds) => const LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
transform: GradientRotation(272 * 3.14159 / 180), // 272度转弧度
|
||||
stops: [0.73, 1.22],
|
||||
colors: [
|
||||
Color(0xFF39CDB9), // #39CDB9 at 73%
|
||||
Color(0xFF2EDA94), // #2EDA94 at 122%
|
||||
],
|
||||
).createShader(bounds),
|
||||
child: Text(
|
||||
bottomRightGradientText!,
|
||||
style: const TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white, // 这个颜色会被shader覆盖
|
||||
letterSpacing: 0.0,
|
||||
height: 1.0, // 设置行高为1,减少额外空间
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 添加状态文本
|
||||
if (bottomRightStatusText != null && bottomRightStatusText!.isNotEmpty) {
|
||||
if (children.isNotEmpty) {
|
||||
children.add(const SizedBox(width: 12.0)); // 间隔12px
|
||||
}
|
||||
|
||||
children.add(
|
||||
Text(
|
||||
bottomRightStatusText!,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Source Han Sans',
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFFCCCCCC), // #CCCCCC
|
||||
letterSpacing: 0.0,
|
||||
height: 1.0, // 设置行高为1,减少额外空间
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center, // 垂直居中对齐
|
||||
textBaseline: TextBaseline.alphabetic, // 统一文本基线
|
||||
children: children,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user