861 lines
26 KiB
Dart
861 lines
26 KiB
Dart
import 'package:flutter/material.dart';
|
||
import '../../../constants/app_constants.dart';
|
||
import 'sp-guide.dart';
|
||
|
||
class BeginnerPage extends StatefulWidget {
|
||
const BeginnerPage({super.key});
|
||
|
||
@override
|
||
State<BeginnerPage> createState() => _BeginnerPageState();
|
||
}
|
||
|
||
class _BeginnerPageState extends State<BeginnerPage>
|
||
with TickerProviderStateMixin {
|
||
final ScrollController _scrollController = ScrollController();
|
||
late AnimationController _fadeController;
|
||
late Animation<double> _fadeAnimation;
|
||
double _progress = 0.0;
|
||
|
||
final List<Map<String, dynamic>> _tutorialSections = [
|
||
{
|
||
'title': '首页功能',
|
||
'icon': Icons.home,
|
||
'emoji': '🏠',
|
||
'color': AppConstants.primaryColor,
|
||
'features': [
|
||
'精美卡片展示',
|
||
'智能推荐:根据时间和情景推荐合适的诗词',
|
||
'诗词详情:显示标题、作者、朝代、正文、注释和赏析',
|
||
'精选诗句:突出显示经典名句',
|
||
'下拉刷新:刷新诗词内容',
|
||
],
|
||
},
|
||
{
|
||
'title': '发现页面',
|
||
'icon': Icons.explore,
|
||
'emoji': '🔍',
|
||
'color': const Color(0xFF00BCD4),
|
||
'features': [
|
||
'分类浏览:按朝代、作者、主题等分类浏览',
|
||
'热门诗词:查看最受欢迎的诗词',
|
||
'活跃排行:查看活跃度最高的诗词',
|
||
'搜索功能:通过关键词搜索诗词',
|
||
'Tab切换:分类、热门、搜索标签页',
|
||
],
|
||
},
|
||
{
|
||
'title': '足迹页面',
|
||
'icon': Icons.history,
|
||
'emoji': '📚',
|
||
'color': const Color(0xFFFF9800),
|
||
'features': [
|
||
'收藏管理:查看和管理所有收藏的诗词',
|
||
'笔记功能:创建和管理诗词笔记',
|
||
'分类展示:全部、点赞、笔记等分类',
|
||
'搜索功能:搜索收藏内容',
|
||
'视图切换:网格和列表视图',
|
||
],
|
||
},
|
||
{
|
||
'title': '个人中心',
|
||
'icon': Icons.person,
|
||
'emoji': '👤',
|
||
'color': const Color(0xFF4CAF50),
|
||
'features': [
|
||
'个人信息:编辑昵称、头像等',
|
||
'统计数据:今日浏览、累计浏览、今日点赞等',
|
||
'数据隐藏:可隐藏统计和答题数据',
|
||
'用户计划:加入用户体验计划',
|
||
'功能入口:设置、了解我们、权限管理等',
|
||
],
|
||
},
|
||
{
|
||
'title': '诗词阅读',
|
||
'icon': Icons.menu_book,
|
||
'emoji': '📖',
|
||
'color': const Color(0xFF9C27B0),
|
||
'features': [
|
||
'加载诗词:点击卡片任意区域加载下一条',
|
||
'查看详情:显示完整诗词信息',
|
||
'点赞诗词:点击心形图标',
|
||
'切换诗词:上一条/下一条按钮',
|
||
'长按复制:长按复制诗词内容',
|
||
],
|
||
},
|
||
{
|
||
'title': '收藏功能',
|
||
'icon': Icons.favorite,
|
||
'emoji': '❤️',
|
||
'color': const Color(0xFFE91E63),
|
||
'features': [
|
||
'一键收藏:点击收藏图标',
|
||
'收藏列表:在足迹页查看',
|
||
'取消收藏:再次点击收藏图标',
|
||
'收藏统计:显示收藏数量',
|
||
'创建笔记:从诗词创建笔记',
|
||
],
|
||
},
|
||
{
|
||
'title': '搜索功能',
|
||
'icon': Icons.search,
|
||
'emoji': '🔎',
|
||
'color': const Color(0xFF009688),
|
||
'features': [
|
||
'关键词搜索:输入关键词搜索',
|
||
'分类筛选:按分类筛选结果',
|
||
'热门搜索:查看热门搜索词',
|
||
'搜索历史:保留搜索记录',
|
||
'实时搜索:输入即时搜索',
|
||
],
|
||
},
|
||
{
|
||
'title': '答题挑战',
|
||
'icon': Icons.quiz,
|
||
'emoji': '🎮',
|
||
'color': const Color(0xFFFF5722),
|
||
'features': [
|
||
'答题挑战:参与诗词答题',
|
||
'题目随机化:使用Fisher-Yates算法',
|
||
'答题记录:记录历史和成绩',
|
||
'答题统计:正确率等数据',
|
||
'提示功能:遇到困难可获取提示',
|
||
],
|
||
},
|
||
{
|
||
'title': '离线模式',
|
||
'icon': Icons.wifi_off,
|
||
'emoji': '📴',
|
||
'color': const Color(0xFF607D8B),
|
||
'features': [
|
||
'离线数据下载:支持下载诗词和答题',
|
||
'下载选项:20/30/60/100条可选',
|
||
'后台下载:返回上一页继续下载',
|
||
'缓存管理:清空缓存可选择内容',
|
||
'自动切换:无网络自动切换',
|
||
],
|
||
},
|
||
{
|
||
'title': '个性化设置',
|
||
'icon': Icons.palette,
|
||
'emoji': '🎨',
|
||
'color': const Color(0xFF3F51B5),
|
||
'features': [
|
||
'主题切换:浅色/深色主题',
|
||
'卡片样式:三种样式可选',
|
||
'颜色自定义:主题色和背景色',
|
||
'圆角调整:卡片圆角大小',
|
||
'字体大小:调整字体大小',
|
||
],
|
||
},
|
||
{
|
||
'title': '投稿功能',
|
||
'icon': Icons.send,
|
||
'emoji': '📝',
|
||
'color': const Color(0xFF00BCD4),
|
||
'features': [
|
||
'诗词投稿:向软件投稿诗词',
|
||
'投稿表单:填写诗词信息',
|
||
'投稿记录:查看历史投稿',
|
||
'相似度检测:防止重复投稿',
|
||
'清空记录:清空投稿历史',
|
||
],
|
||
},
|
||
{
|
||
'title': '投票功能',
|
||
'icon': Icons.how_to_vote,
|
||
'emoji': '🗳️',
|
||
'color': const Color(0xFF795548),
|
||
'features': [
|
||
'用户投票:参与功能投票',
|
||
'投票结果:查看统计',
|
||
'登录注册:用户身份',
|
||
'自动注册:简化流程',
|
||
'投票详情:查看选项',
|
||
],
|
||
},
|
||
{
|
||
'title': '桌面卡片',
|
||
'icon': Icons.wb_sunny,
|
||
'emoji': '🌤️',
|
||
'color': const Color(0xFFFFC107),
|
||
'features': [
|
||
'天气显示:显示当前天气',
|
||
'城市显示:所在城市',
|
||
'十二时辰:中国传统计时',
|
||
'时间标签:子丑寅卯辰巳午未申酉戌亥',
|
||
'智能更新:自动更新时间',
|
||
],
|
||
},
|
||
{
|
||
'title': '图片分享',
|
||
'icon': Icons.share,
|
||
'emoji': '📸',
|
||
'color': const Color(0xFF03A9F4),
|
||
'features': [
|
||
'诗词分享:生成图片分享',
|
||
'软件分享:分享给朋友',
|
||
'复制功能:复制内容',
|
||
'高清图片:生成高质量图片',
|
||
'跨平台:支持多平台分享',
|
||
],
|
||
},
|
||
{
|
||
'title': '数据管理',
|
||
'icon': Icons.storage,
|
||
'emoji': '💾',
|
||
'color': const Color(0xFF8BC34A),
|
||
'features': [
|
||
'数据统计:显示数据占用',
|
||
'清空数据:清空应用数据',
|
||
'数据备份:备份数据',
|
||
'缓存管理:管理缓存',
|
||
'离线数据:管理离线数据',
|
||
],
|
||
},
|
||
{
|
||
'title': '帮助与反馈',
|
||
'icon': Icons.help,
|
||
'emoji': '❓',
|
||
'color': const Color(0xFF9E9E9E),
|
||
'features': [
|
||
'使用指南:查看使用说明',
|
||
'常见问题:FAQ解答',
|
||
'用户反馈:反馈问题',
|
||
'功能建议:提交建议',
|
||
'已知Bug:查看Bug列表',
|
||
],
|
||
},
|
||
];
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_scrollController.addListener(_onScroll);
|
||
_fadeController = AnimationController(
|
||
duration: const Duration(milliseconds: 500),
|
||
vsync: this,
|
||
);
|
||
_fadeAnimation = CurvedAnimation(
|
||
parent: _fadeController,
|
||
curve: Curves.easeIn,
|
||
);
|
||
_fadeController.forward();
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_scrollController.removeListener(_onScroll);
|
||
_scrollController.dispose();
|
||
_fadeController.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
void _onScroll() {
|
||
if (_scrollController.hasClients) {
|
||
final maxScroll = _scrollController.position.maxScrollExtent;
|
||
final currentScroll = _scrollController.position.pixels;
|
||
final progress = maxScroll > 0 ? currentScroll / maxScroll : 0.0;
|
||
|
||
if (mounted) {
|
||
setState(() {
|
||
_progress = progress;
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
backgroundColor: Colors.grey[50],
|
||
body: Stack(
|
||
children: [
|
||
FadeTransition(
|
||
opacity: _fadeAnimation,
|
||
child: CustomScrollView(
|
||
controller: _scrollController,
|
||
slivers: [
|
||
SliverAppBar(
|
||
title: const Text(
|
||
'软件功能',
|
||
style: TextStyle(
|
||
fontWeight: FontWeight.bold,
|
||
fontSize: 17,
|
||
color: AppConstants.primaryColor,
|
||
),
|
||
),
|
||
backgroundColor: Colors.white,
|
||
foregroundColor: AppConstants.primaryColor,
|
||
elevation: 0,
|
||
centerTitle: true,
|
||
floating: true,
|
||
snap: true,
|
||
pinned: false,
|
||
actions: [
|
||
IconButton(
|
||
icon: const Icon(Icons.help_outline),
|
||
color: AppConstants.primaryColor,
|
||
onPressed: () {
|
||
Navigator.push(
|
||
context,
|
||
MaterialPageRoute(
|
||
builder: (context) =>
|
||
const SpGuidePage(fromSettings: true),
|
||
),
|
||
);
|
||
},
|
||
),
|
||
],
|
||
),
|
||
SliverPadding(
|
||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 100),
|
||
sliver: SliverList(
|
||
delegate: SliverChildBuilderDelegate((context, index) {
|
||
return _buildSectionCard(_tutorialSections[index], index);
|
||
}, childCount: _tutorialSections.length),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
_buildProgressIndicator(),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildSectionCard(Map<String, dynamic> section, int index) {
|
||
return TweenAnimationBuilder<double>(
|
||
tween: Tween(begin: 0.0, end: 1.0),
|
||
duration: Duration(milliseconds: 300 + (index * 50)),
|
||
curve: Curves.easeOut,
|
||
builder: (context, value, child) {
|
||
return Transform.translate(
|
||
offset: Offset(0, 20 * (1 - value)),
|
||
child: Opacity(opacity: value, child: child),
|
||
);
|
||
},
|
||
child: Container(
|
||
margin: const EdgeInsets.only(bottom: 16),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(16),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.black.withValues(alpha: 0.05),
|
||
blurRadius: 12,
|
||
offset: const Offset(0, 2),
|
||
),
|
||
],
|
||
),
|
||
child: Padding(
|
||
padding: const EdgeInsets.all(20),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
Container(
|
||
width: 48,
|
||
height: 48,
|
||
decoration: BoxDecoration(
|
||
color: (section['color'] as Color).withValues(alpha: 0.1),
|
||
borderRadius: BorderRadius.circular(14),
|
||
),
|
||
child: Center(
|
||
child: Text(
|
||
section['emoji'],
|
||
style: const TextStyle(fontSize: 24),
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 16),
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
section['title'],
|
||
style: const TextStyle(
|
||
fontSize: 18,
|
||
fontWeight: FontWeight.w600,
|
||
color: Colors.black87,
|
||
letterSpacing: -0.3,
|
||
),
|
||
),
|
||
const SizedBox(height: 4),
|
||
Text(
|
||
'第 ${index + 1} 部分',
|
||
style: TextStyle(
|
||
fontSize: 13,
|
||
color: Colors.grey[500],
|
||
fontWeight: FontWeight.w400,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 20),
|
||
_buildSectionContent(section['features'], section['color']),
|
||
const SizedBox(height: 16),
|
||
if (index < 4) ...[
|
||
const Divider(height: 1, color: Color(0xFFF5F5F5)),
|
||
const SizedBox(height: 16),
|
||
_buildPreviewSection(section['title']),
|
||
],
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildSectionContent(List<String> features, Color color) {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: features.map((feature) {
|
||
return Padding(
|
||
padding: const EdgeInsets.only(bottom: 12),
|
||
child: Row(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Container(
|
||
width: 6,
|
||
height: 6,
|
||
margin: const EdgeInsets.only(top: 8, right: 12),
|
||
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
||
),
|
||
Expanded(
|
||
child: Text(
|
||
feature,
|
||
style: TextStyle(
|
||
fontSize: 15,
|
||
color: Colors.grey[700],
|
||
height: 1.5,
|
||
fontWeight: FontWeight.w400,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}).toList(),
|
||
);
|
||
}
|
||
|
||
Widget _buildPreviewSection(String title) {
|
||
Widget preview;
|
||
switch (title) {
|
||
case '首页功能':
|
||
preview = _buildHomePreview();
|
||
break;
|
||
case '发现页面':
|
||
preview = _buildDiscoverPreview();
|
||
break;
|
||
case '足迹页面':
|
||
preview = _buildFootprintPreview();
|
||
break;
|
||
case '个人中心':
|
||
preview = _buildProfilePreview();
|
||
break;
|
||
default:
|
||
preview = const SizedBox.shrink();
|
||
}
|
||
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
Icon(
|
||
Icons.visibility_outlined,
|
||
size: 16,
|
||
color: AppConstants.primaryColor,
|
||
),
|
||
const SizedBox(width: 6),
|
||
Text(
|
||
'界面预览',
|
||
style: TextStyle(
|
||
fontSize: 13,
|
||
fontWeight: FontWeight.w600,
|
||
color: AppConstants.primaryColor,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 12),
|
||
preview,
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildHomePreview() {
|
||
return Container(
|
||
padding: const EdgeInsets.all(16),
|
||
decoration: BoxDecoration(
|
||
color: Colors.grey[100],
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
Container(
|
||
width: 32,
|
||
height: 32,
|
||
decoration: BoxDecoration(
|
||
color: AppConstants.primaryColor.withValues(alpha: 0.1),
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
child: Icon(
|
||
Icons.book,
|
||
size: 18,
|
||
color: AppConstants.primaryColor,
|
||
),
|
||
),
|
||
const SizedBox(width: 10),
|
||
Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
'静夜思',
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: Colors.grey[800],
|
||
),
|
||
),
|
||
Text(
|
||
'唐·李白',
|
||
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 12),
|
||
Container(
|
||
padding: const EdgeInsets.all(12),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
child: Text(
|
||
'床前明月光,疑是地上霜。\n举头望明月,低头思故乡。',
|
||
style: TextStyle(
|
||
fontSize: 14,
|
||
color: Colors.grey[700],
|
||
height: 1.6,
|
||
),
|
||
textAlign: TextAlign.center,
|
||
),
|
||
),
|
||
const SizedBox(height: 12),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
children: [
|
||
_buildPreviewAction(Icons.favorite_border, '点赞'),
|
||
_buildPreviewAction(Icons.bookmark_border, '收藏'),
|
||
_buildPreviewAction(Icons.share_outlined, '分享'),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildDiscoverPreview() {
|
||
return Container(
|
||
padding: const EdgeInsets.all(16),
|
||
decoration: BoxDecoration(
|
||
color: Colors.grey[100],
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(10),
|
||
),
|
||
child: Row(
|
||
children: [
|
||
Icon(Icons.search, size: 18, color: Colors.grey[400]),
|
||
const SizedBox(width: 8),
|
||
Text(
|
||
'搜索诗词...',
|
||
style: TextStyle(fontSize: 14, color: Colors.grey[400]),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
const SizedBox(height: 12),
|
||
Row(
|
||
children: [
|
||
_buildPreviewTag('唐诗'),
|
||
const SizedBox(width: 8),
|
||
_buildPreviewTag('宋词'),
|
||
const SizedBox(width: 8),
|
||
_buildPreviewTag('元曲'),
|
||
],
|
||
),
|
||
const SizedBox(height: 12),
|
||
_buildPreviewListItem('将进酒', '李白'),
|
||
const SizedBox(height: 8),
|
||
_buildPreviewListItem('水调歌头', '苏轼'),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildFootprintPreview() {
|
||
return Container(
|
||
padding: const EdgeInsets.all(16),
|
||
decoration: BoxDecoration(
|
||
color: Colors.grey[100],
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
children: [
|
||
_buildPreviewStat('128', '收藏'),
|
||
_buildPreviewStat('45', '笔记'),
|
||
_buildPreviewStat('89', '点赞'),
|
||
],
|
||
),
|
||
const SizedBox(height: 12),
|
||
_buildPreviewListItem('静夜思', '已收藏'),
|
||
const SizedBox(height: 8),
|
||
_buildPreviewListItem('春晓', '有笔记'),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildProfilePreview() {
|
||
return Container(
|
||
padding: const EdgeInsets.all(16),
|
||
decoration: BoxDecoration(
|
||
color: Colors.grey[100],
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
children: [
|
||
Container(
|
||
width: 48,
|
||
height: 48,
|
||
decoration: BoxDecoration(
|
||
color: AppConstants.primaryColor.withValues(alpha: 0.2),
|
||
borderRadius: BorderRadius.circular(24),
|
||
),
|
||
child: const Center(
|
||
child: Text('👤', style: TextStyle(fontSize: 24)),
|
||
),
|
||
),
|
||
const SizedBox(width: 12),
|
||
Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
'诗词爱好者',
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: Colors.grey[800],
|
||
),
|
||
),
|
||
Text(
|
||
'Lv.12 · 诗意生活',
|
||
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 12),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
children: [
|
||
_buildPreviewStat('156', '浏览'),
|
||
_buildPreviewStat('89', '点赞'),
|
||
_buildPreviewStat('45', '答题'),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildPreviewAction(IconData icon, String label) {
|
||
return Column(
|
||
children: [
|
||
Icon(icon, size: 20, color: Colors.grey[600]),
|
||
const SizedBox(height: 4),
|
||
Text(label, style: TextStyle(fontSize: 11, color: Colors.grey[600])),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildPreviewTag(String text) {
|
||
return Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(16),
|
||
border: Border.all(
|
||
color: AppConstants.primaryColor.withValues(alpha: 0.3),
|
||
),
|
||
),
|
||
child: Text(
|
||
text,
|
||
style: TextStyle(
|
||
fontSize: 12,
|
||
color: AppConstants.primaryColor,
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildPreviewListItem(String title, String subtitle) {
|
||
return Container(
|
||
padding: const EdgeInsets.all(10),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
Text(
|
||
title,
|
||
style: TextStyle(
|
||
fontSize: 14,
|
||
color: Colors.grey[700],
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
),
|
||
Text(
|
||
subtitle,
|
||
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildPreviewStat(String value, String label) {
|
||
return Column(
|
||
children: [
|
||
Text(
|
||
value,
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: AppConstants.primaryColor,
|
||
),
|
||
),
|
||
const SizedBox(height: 2),
|
||
Text(label, style: TextStyle(fontSize: 11, color: Colors.grey[500])),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildProgressIndicator() {
|
||
return Positioned(
|
||
left: 0,
|
||
top: 0,
|
||
bottom: 0,
|
||
child: Container(
|
||
width: 60,
|
||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||
decoration: BoxDecoration(
|
||
gradient: LinearGradient(
|
||
begin: Alignment.centerLeft,
|
||
end: Alignment.centerRight,
|
||
colors: [
|
||
Colors.white.withValues(alpha: 0.95),
|
||
Colors.white.withValues(alpha: 0.85),
|
||
Colors.white.withValues(alpha: 0.0),
|
||
],
|
||
stops: const [0.0, 0.7, 1.0],
|
||
),
|
||
),
|
||
child: Column(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
Container(
|
||
width: 8,
|
||
height: 200,
|
||
decoration: BoxDecoration(
|
||
color: Colors.grey[200],
|
||
borderRadius: BorderRadius.circular(4),
|
||
),
|
||
child: Stack(
|
||
children: [
|
||
AnimatedPositioned(
|
||
duration: const Duration(milliseconds: 200),
|
||
curve: Curves.easeOut,
|
||
top: _progress * 160,
|
||
child: Container(
|
||
width: 8,
|
||
height: 40,
|
||
decoration: BoxDecoration(
|
||
color: AppConstants.primaryColor,
|
||
borderRadius: BorderRadius.circular(4),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: AppConstants.primaryColor.withValues(
|
||
alpha: 0.3,
|
||
),
|
||
blurRadius: 8,
|
||
offset: const Offset(0, 2),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
const SizedBox(height: 12),
|
||
AnimatedContainer(
|
||
duration: const Duration(milliseconds: 200),
|
||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||
decoration: BoxDecoration(
|
||
color: AppConstants.primaryColor,
|
||
borderRadius: BorderRadius.circular(8),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: AppConstants.primaryColor.withValues(alpha: 0.2),
|
||
blurRadius: 4,
|
||
offset: const Offset(0, 2),
|
||
),
|
||
],
|
||
),
|
||
child: Text(
|
||
'${(_progress * 100).toInt()}%',
|
||
style: const TextStyle(
|
||
color: Colors.white,
|
||
fontSize: 12,
|
||
fontWeight: FontWeight.w600,
|
||
letterSpacing: -0.2,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|