- 管理页:单元集 / 计划 / 算法三个维度,卡片带元数据 - 账户页:资料、学习数据、竖直分组的四个功能入口 - 新增设置、文档与帮助(底部可上滑助手)、反馈、关于四个页面 - 抽出 StatBlock 与 GroupedListSection 共用组件 - 关闭 Android 预测式返回,转场改为 M3 水平滑入
167 lines
4.5 KiB
Dart
167 lines
4.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../models/account_profile.dart';
|
|
import '../widgets/grouped_list_section.dart';
|
|
import '../widgets/stat_block.dart';
|
|
import 'about_page.dart';
|
|
import 'docs_page.dart';
|
|
import 'feedback_page.dart';
|
|
import 'settings_page.dart';
|
|
|
|
/// 账户页:资料、学习数据、功能入口。
|
|
class AccountPage extends StatelessWidget {
|
|
const AccountPage({super.key});
|
|
|
|
static const AccountProfile _profile = AccountProfile.sample;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('账户')),
|
|
body: ListView(
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 24),
|
|
children: const <Widget>[
|
|
_ProfileCard(profile: _profile),
|
|
SizedBox(height: 12),
|
|
_StatsCard(profile: _profile),
|
|
SizedBox(height: 22),
|
|
_ActionList(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ProfileCard extends StatelessWidget {
|
|
const _ProfileCard({required this.profile});
|
|
|
|
final AccountProfile profile;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final ThemeData theme = Theme.of(context);
|
|
final ColorScheme colors = theme.colorScheme;
|
|
|
|
return Container(
|
|
padding: const EdgeInsets.all(16),
|
|
decoration: BoxDecoration(
|
|
color: colors.surfaceContainerLow,
|
|
borderRadius: BorderRadius.circular(20),
|
|
),
|
|
child: Row(
|
|
children: <Widget>[
|
|
CircleAvatar(
|
|
radius: 30,
|
|
backgroundColor: colors.primaryContainer,
|
|
child: Text(
|
|
profile.displayName.characters.first,
|
|
style: theme.textTheme.titleLarge?.copyWith(
|
|
color: colors.onPrimaryContainer,
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 16),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
Text(
|
|
profile.displayName,
|
|
style: theme.textTheme.titleMedium,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
'ID ${profile.userId} · ${profile.stage}',
|
|
style: theme.textTheme.bodySmall?.copyWith(
|
|
color: colors.onSurfaceVariant,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.chevron_right_rounded,
|
|
color: colors.onSurfaceVariant,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _StatsCard extends StatelessWidget {
|
|
const _StatsCard({required this.profile});
|
|
|
|
final AccountProfile profile;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(18),
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
|
borderRadius: BorderRadius.circular(20),
|
|
),
|
|
child: Row(
|
|
children: <Widget>[
|
|
Expanded(
|
|
child: StatBlock(
|
|
label: '累计学习',
|
|
value: '${profile.totalHours}',
|
|
unit: '小时',
|
|
),
|
|
),
|
|
Expanded(
|
|
child: StatBlock(
|
|
label: '坚持',
|
|
value: '${profile.streakDays}',
|
|
unit: '天',
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 竖直排列的长按钮列表,样式参考原生 Android 设置页。
|
|
class _ActionList extends StatelessWidget {
|
|
const _ActionList();
|
|
|
|
static const List<(IconData, String)> _items = <(IconData, String)>[
|
|
(Icons.settings_outlined, '设置'),
|
|
(Icons.menu_book_outlined, '文档与帮助'),
|
|
(Icons.feedback_outlined, '反馈问题'),
|
|
(Icons.info_outline_rounded, '关于 KiriMemo'),
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return GroupedListSection(
|
|
tiles: <Widget>[
|
|
for (final (IconData icon, String label) in _items)
|
|
GroupedListTile(
|
|
icon: icon,
|
|
title: label,
|
|
onTap: () => _open(context, label),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
void _open(BuildContext context, String label) {
|
|
final Widget page = switch (label) {
|
|
'设置' => const SettingsPage(),
|
|
'文档与帮助' => const DocsPage(),
|
|
'反馈问题' => const FeedbackPage(),
|
|
_ => const AboutPage(),
|
|
};
|
|
Navigator.of(context).push(
|
|
MaterialPageRoute<void>(builder: (BuildContext _) => page),
|
|
);
|
|
}
|
|
}
|