feat(leetcode_card): 优化界面展示效果并添加刷新动画

- 增加 AnimationController 以实现刷新动画效果
- 调整文本样式和大小,提升可读性
- 在用户击败百分比和最近提交部分增加加粗显示
- 优化提交记录为空时的显示效果
- 在刷新按钮周围添加旋转动画
This commit is contained in:
高手 2025-06-10 15:50:21 +08:00
parent ab623efeb0
commit a4c1a2aeda

View File

@ -12,7 +12,10 @@ class LeetCodeCard extends StatefulWidget {
State<LeetCodeCard> createState() => _LeetCodeCardState();
}
class _LeetCodeCardState extends State<LeetCodeCard> {
class _LeetCodeCardState extends State<LeetCodeCard>
with SingleTickerProviderStateMixin {
late AnimationController _refreshController;
List<dynamic> _submissions = [];
Map<String, dynamic>? _progress;
bool _isLoading = false;
@ -118,6 +121,10 @@ class _LeetCodeCardState extends State<LeetCodeCard> {
void initState() {
super.initState();
_fetchData();
_refreshController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
}
Widget _buildProgressCard() {
@ -135,7 +142,7 @@ class _LeetCodeCardState extends State<LeetCodeCard> {
children: [
const Text(
'解题进度',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
...acceptedQuestions.map((q) {
@ -153,8 +160,13 @@ class _LeetCodeCardState extends State<LeetCodeCard> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('击败用户'),
Text('${totalBeatsPercentage.toStringAsFixed(1)}%'),
const Text('击败用户',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('${totalBeatsPercentage.toStringAsFixed(1)}%',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Colors.green)),
],
),
],
@ -176,19 +188,34 @@ class _LeetCodeCardState extends State<LeetCodeCard> {
children: [
const Text(
'LeetCode 最近提交',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
RotationTransition(
turns: _refreshController,
child: IconButton(
icon: const Icon(Icons.refresh, size: 28),
onPressed: _isLoading
? null
: () async {
_refreshController.forward(from: 0.0);
await _fetchData();
},
),
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _isLoading ? null : _fetchData,
),
],
),
if (_isLoading)
const Center(
Center(
child: Padding(
padding: EdgeInsets.all(16.0),
child: CircularProgressIndicator(),
padding: const EdgeInsets.all(16.0),
child: AnimatedBuilder(
animation: _refreshController,
builder: (_, child) => Transform.rotate(
angle: _refreshController.value * 2 * 3.14,
child: child,
),
child: const CircularProgressIndicator(),
),
),
)
else if (_error != null)
@ -212,7 +239,8 @@ class _LeetCodeCardState extends State<LeetCodeCard> {
const Center(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text('暂无提交记录'),
child:
Text('暂无提交记录', style: TextStyle(fontSize: 16)),
),
)
else
@ -228,12 +256,16 @@ class _LeetCodeCardState extends State<LeetCodeCard> {
title: Text(
question['translatedTitle'] ??
question['title'],
style: const TextStyle(fontSize: 16),
),
subtitle: Text(
'提交时间: ${timeago.format(DateTime.fromMillisecondsSinceEpoch(submission['submitTime'] * 1000), locale: 'zh_CN')}',
style: const TextStyle(fontSize: 14),
),
trailing: Text(
'#${question['questionFrontendId']}',
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
);
},