重构
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user