import 'package:flutter/material.dart'; import '../app_info.dart'; /// 设置页,按 Android 系统设置的分组列表组织。 class SettingsPage extends StatefulWidget { const SettingsPage({super.key}); @override State createState() => _SettingsPageState(); } class _SettingsPageState extends State { bool _requeueOnWrong = true; bool _readAloud = true; bool _autoSync = true; bool _wifiOnly = true; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('设置')), body: ListView( padding: const EdgeInsets.only(bottom: 32), children: [ const _SectionHeader('学习'), _ValueTile( icon: Icons.school_outlined, title: '每日新识记上限', value: '35 条', onTap: () => _pending('每日新识记上限'), ), _ValueTile( icon: Icons.replay_rounded, title: '每日复习上限', value: '200 条', onTap: () => _pending('每日复习上限'), ), _ValueTile( icon: Icons.schedule_rounded, title: '学习时段', value: '08:00–23:00', onTap: () => _pending('学习时段'), ), _SwitchTile( icon: Icons.restart_alt_rounded, title: '答错后重新排队', subtitle: '同一轮里再出现一次', value: _requeueOnWrong, onChanged: (bool value) => setState(() => _requeueOnWrong = value), ), const _SectionHeader('测验'), _ValueTile( icon: Icons.quiz_outlined, title: '默认谜题类型', value: '完形填空', onTap: () => _pending('默认谜题类型'), ), _SwitchTile( icon: Icons.volume_up_outlined, title: '自动朗读', subtitle: '进入谜题时播放语音', value: _readAloud, onChanged: (bool value) => setState(() => _readAloud = value), ), const _SectionHeader('外观'), _ValueTile( icon: Icons.dark_mode_outlined, title: '主题', value: '跟随系统', onTap: () => _pending('主题'), ), _ValueTile( icon: Icons.text_fields_rounded, title: '字号', value: '标准', onTap: () => _pending('字号'), ), const _SectionHeader('同步'), _SwitchTile( icon: Icons.cloud_sync_outlined, title: '自动同步', subtitle: '学完一轮后自动上传', value: _autoSync, onChanged: (bool value) => setState(() => _autoSync = value), ), _SwitchTile( icon: Icons.wifi_rounded, title: '仅在 Wi-Fi 下同步', value: _wifiOnly, onChanged: (bool value) => setState(() => _wifiOnly = value), ), _ValueTile( icon: Icons.sync_rounded, title: '立即同步', onTap: () => _pending('立即同步'), ), const _SectionHeader('关于'), _ValueTile( icon: Icons.info_outline_rounded, title: '版本', value: appVersion, ), _ValueTile( icon: Icons.description_outlined, title: '开源许可', onTap: () => _pending('开源许可'), ), ], ), ); } void _pending(String feature) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('$feature 尚未接入内核'), behavior: SnackBarBehavior.floating, ), ); } } class _SectionHeader extends StatelessWidget { const _SectionHeader(this.title); final String title; @override Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); return Padding( padding: const EdgeInsets.fromLTRB(16, 20, 16, 6), child: Text( title, style: theme.textTheme.labelLarge?.copyWith( color: theme.colorScheme.primary, fontWeight: FontWeight.w600, ), ), ); } } class _ValueTile extends StatelessWidget { const _ValueTile({ required this.icon, required this.title, this.value, this.onTap, }); final IconData icon; final String title; final String? value; final VoidCallback? onTap; @override Widget build(BuildContext context) { final ColorScheme colors = Theme.of(context).colorScheme; final String? value = this.value; return ListTile( leading: Icon(icon, color: colors.onSurfaceVariant), title: Text(title), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ if (value != null) Text( value, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: colors.onSurfaceVariant, ), ), if (onTap != null) ...[ const SizedBox(width: 4), Icon( Icons.chevron_right_rounded, size: 20, color: colors.onSurfaceVariant, ), ], ], ), onTap: onTap, ); } } class _SwitchTile extends StatelessWidget { const _SwitchTile({ required this.icon, required this.title, required this.value, required this.onChanged, this.subtitle, }); final IconData icon; final String title; final String? subtitle; final bool value; final ValueChanged onChanged; @override Widget build(BuildContext context) { final ColorScheme colors = Theme.of(context).colorScheme; return SwitchListTile( secondary: Icon(icon, color: colors.onSurfaceVariant), title: Text(title), subtitle: subtitle == null ? null : Text(subtitle!), value: value, onChanged: onChanged, ); } }