release 1.3.1
This commit is contained in:
@@ -0,0 +1,860 @@
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user