This commit is contained in:
Developer
2026-03-31 03:48:14 +08:00
parent 62729615b7
commit 888363785b
26 changed files with 219 additions and 808 deletions

View File

@@ -4,16 +4,13 @@
/// 最新变化: 重新设计布局,实现朋友圈风格的个人页面
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import '../../constants/app_constants.dart';
import '../../controllers/history_controller.dart';
import '../../controllers/sqlite_storage_controller.dart';
import '../../utils/flutter_compatibility_fix.dart';
import '../../controllers/shared_preferences_storage_controller.dart';
import 'history_page.dart';
import 'per_card.dart';
import 'settings/app_fun.dart';
@@ -23,7 +20,6 @@ import 'settings/privacy.dart';
import 'settings/learn-us.dart';
import 'app-info.dart';
import 'level/poetry.dart';
import 'guide/sp-guide.dart';
import 'guide/permission.dart';
import 'guide/app-data.dart';
import 'theme/app-diy.dart';
@@ -47,10 +43,8 @@ class _ProfilePageState extends State<ProfilePage>
double _startY = 0.0;
// 历史记录相关
List<Map<String, dynamic>> _poetryHistory = [];
final String _historyKey = 'poetry_history';
// 答题统计数据
int _totalQuestions = 0;
int _correctAnswers = 0;
int _todayQuestions = 0;
int _weekQuestions = 0;
@@ -86,10 +80,6 @@ class _ProfilePageState extends State<ProfilePage>
super.dispose();
}
void _handleScroll() {
// 这个方法现在由手势检测处理
}
void _onPageChanged(int page) {
setState(() {
_currentPage = page;
@@ -107,55 +97,21 @@ class _ProfilePageState extends State<ProfilePage>
} catch (e) {}
}
Future<void> _savePoetryToHistory(Map<String, dynamic> poetryData) async {
try {
final success = await HistoryController.addToHistory(poetryData);
if (success) {
_showSnackBar('已添加到历史记录');
} else {
_showSnackBar('该诗词已在历史记录中');
}
} catch (e) {
_showSnackBar('保存失败');
}
}
Future<void> _clearPoetryHistory() async {
try {
final success = await HistoryController.clearHistory();
if (success) {
setState(() {
_poetryHistory.clear();
});
_showSnackBar('历史记录已清空');
} else {
_showSnackBar('清空失败');
}
} catch (e) {
_showSnackBar('清空失败');
}
}
// === 答题统计相关方法 ===
Future<void> _loadPoetryStatistics() async {
try {
// 加载总体统计
_totalQuestions = await SQLiteStorageController.getInt(
'totalQuestions',
defaultValue: 0,
);
_correctAnswers = await SQLiteStorageController.getInt(
_correctAnswers = await SharedPreferencesStorageController.getInt(
'correctAnswers',
defaultValue: 0,
);
// 加载答题记录列表来计算今日和本周答题数
List<String> records = await SQLiteStorageController.getStringList(
'poetryAnswerRecords',
defaultValue: [],
);
List<String> records =
await SharedPreferencesStorageController.getStringList(
'poetryAnswerRecords',
defaultValue: [],
);
final now = DateTime.now();
final todayStart = DateTime(now.year, now.month, now.day);
@@ -287,158 +243,6 @@ class _ProfilePageState extends State<ProfilePage>
);
}
Widget _buildStatCard(String label, String value, IconData icon) {
// === 单个统计卡片:显示统计数据和图标 ===
return Expanded(
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 5,
offset: const Offset(0, 1),
),
],
),
child: Column(
children: [
Icon(icon, color: AppConstants.primaryColor, size: 24),
const SizedBox(height: 8),
Text(
value,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 4),
Text(
label,
style: const TextStyle(fontSize: 12, color: Colors.grey),
textAlign: TextAlign.center,
),
],
),
),
);
}
Widget _buildTabBar() {
// === 页面切换标签栏:显示当前页面指示器 ===
return GestureDetector(
behavior: HitTestBehavior.opaque,
onVerticalDragStart: (_) {},
onVerticalDragUpdate: (_) {},
onVerticalDragEnd: (_) {},
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppConstants.primaryColor.withValues(alpha: 0.85),
AppConstants.primaryColor.withValues(alpha: 0.8),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
// 页面指示器
Expanded(
child: Container(
height: 3,
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(2),
),
child: Stack(
children: [
// 背景条
Container(
height: 3,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(2),
),
),
// 滑动指示器
AnimatedContainer(
duration: const Duration(milliseconds: 300),
width: MediaQuery.of(context).size.width / 3 - 40,
height: 3,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
),
margin: EdgeInsets.only(
left:
(MediaQuery.of(context).size.width / 3 - 40) *
_currentPage,
),
),
],
),
),
),
// 页面标签
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildTabLabel(0, '卡片'),
_buildTabLabel(1, '设置'),
_buildTabLabel(2, '更多'),
],
),
),
],
),
),
),
);
}
Widget _buildTabLabel(int index, String label) {
// === 单个页面标签:可点击切换到对应页面 ===
final isSelected = _currentPage == index;
return GestureDetector(
onTap: () {
// 添加 mounted 和 hasClients 检查,避免 dispose 后调用导致黑屏
if (mounted && _pageController.hasClients) {
_pageController.animateToPage(
index,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(
label,
style: TextStyle(
color: isSelected ? Colors.white : Colors.white70,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
fontSize: 14,
),
),
),
);
}
Widget _buildPage1() {
// === 第1页个人信息卡片展示 ===
return SingleChildScrollView(
@@ -914,15 +718,6 @@ class _ProfilePageState extends State<ProfilePage>
);
}
void _navigateToSpGuidePage() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SpGuidePage(fromSettings: true),
),
);
}
void _navigateToPermissionPage() {
Navigator.push(
context,
@@ -972,129 +767,7 @@ class _ProfilePageState extends State<ProfilePage>
);
}
// === 历史记录对话框 ===
void _showHistoryDialog() {
showDialog(
context: context,
builder: (context) => Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: Container(
width: MediaQuery.of(context).size.width * 0.9,
height: MediaQuery.of(context).size.height * 0.7,
padding: const EdgeInsets.all(20),
child: Column(
children: [
// 对话框标题
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'历史记录',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppConstants.primaryColor,
),
),
Row(
children: [
TextButton(
onPressed: _poetryHistory.isEmpty
? null
: () {
Navigator.pop(context);
_clearPoetryHistory();
},
child: const Text('清空'),
),
IconButton(
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.close),
),
],
),
],
),
const SizedBox(height: 16),
// 历史记录列表
Expanded(
child: _poetryHistory.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.history,
size: 64,
color: Colors.grey[400],
),
const SizedBox(height: 16),
Text(
'暂无历史记录',
style: TextStyle(
fontSize: 16,
color: Colors.grey[600],
),
),
],
),
)
: ListView.builder(
itemCount: _poetryHistory.length,
itemBuilder: (context, index) {
final poetry = _poetryHistory[index];
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: CircleAvatar(
radius: 20,
backgroundColor: AppConstants.primaryColor
.withValues(alpha: 0.1),
child: Text(
'${index + 1}',
style: TextStyle(
fontSize: 12,
color: AppConstants.primaryColor,
fontWeight: FontWeight.bold,
),
),
),
title: Text(
poetry['name'] ?? '未知诗词',
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
'${poetry['alias'] ?? '未知朝代'}${poetry['date'] ?? ''}',
style: const TextStyle(
fontSize: 12,
color: Colors.grey,
),
),
trailing: IconButton(
icon: const Icon(Icons.favorite_border),
onPressed: () {
Navigator.pop(context);
_showSnackBar('已添加到收藏');
},
),
),
);
},
),
),
],
),
),
),
);
}
Widget? _showMoreOptions() {
void _showMoreOptions() {
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,