diff --git a/fonts/custom.ttf b/fonts/custom.ttf new file mode 100644 index 0000000..2ca97e8 Binary files /dev/null and b/fonts/custom.ttf differ diff --git a/lib/layout/app_drawer.dart b/lib/layout/app_drawer.dart index be3990f..0b1bc56 100644 --- a/lib/layout/app_drawer.dart +++ b/lib/layout/app_drawer.dart @@ -1,21 +1,24 @@ +import 'package:flisp_app/provider/app_provider.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import '../provider/app_provider.dart'; - class AppDrawer extends StatelessWidget { const AppDrawer({super.key}); - DrawerHeader buildDrawerHeader() { + DrawerHeader buildDrawerHeader(BuildContext context) { return DrawerHeader( - decoration: BoxDecoration(color: Colors.blue.shade700), - child: const Column( + decoration: BoxDecoration(color: Theme.of(context).primaryColor), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ CircleAvatar( radius: 30, backgroundColor: Colors.white, - child: Icon(Icons.flash_on, color: Colors.blue, size: 40), + child: Icon( + Icons.flash_on, + color: Theme.of(context).colorScheme.primary, + size: 40, + ), ), SizedBox(height: 10), Text( @@ -35,36 +38,170 @@ class AppDrawer extends StatelessWidget { ); } + Widget _buildDarkModeSection(BuildContext context, AppProvider appProvider) { + return ListTile( + leading: Icon( + appProvider.isDarkMode ? Icons.dark_mode : Icons.light_mode, + color: Theme.of(context).colorScheme.primary, + ), + title: const Text('暗黑模式'), + trailing: Switch( + value: appProvider.isDarkMode, + onChanged: (value) { + appProvider.toggleDarkMode(value); + }, + ), + onTap: () { + appProvider.toggleDarkMode(!appProvider.isDarkMode); + }, + ); + } + + Widget _buildThemeColorList(BuildContext context, AppProvider appProvider) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + child: GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + childAspectRatio: 1.2, + ), + itemCount: appProvider.availableThemes.length, + itemBuilder: (context, index) { + final themeColor = appProvider.availableThemes[index]; + final isSelected = appProvider.currentTheme == themeColor; + + return _buildThemeColorItem( + themeColor: themeColor, + isSelected: isSelected, + onTap: () => appProvider.changeTheme(themeColor), + ); + }, + ), + ); + } + + Widget _buildThemeColorItem({ + required ThemeColor themeColor, + required bool isSelected, + required VoidCallback onTap, + }) { + return GestureDetector( + onTap: onTap, + child: Container( + decoration: BoxDecoration( + color: + isSelected + ? themeColor.primaryColor.withAlpha(50) + : Colors.transparent, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: isSelected ? themeColor.primaryColor : Colors.grey.shade300, + width: isSelected ? 2 : 1, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // 颜色圆点 + Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: themeColor.primaryColor, + shape: BoxShape.circle, + border: Border.all(color: Colors.white, width: 2), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(10), + blurRadius: 2, + offset: const Offset(0, 1), + ), + ], + ), + ), + const SizedBox(height: 4), + Text( + themeColor.name, + style: TextStyle( + fontSize: 10, + fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, + color: + isSelected ? themeColor.primaryColor : Colors.grey.shade600, + ), + ), + ], + ), + ), + ); + } + + Widget _buildThemeSection(BuildContext context, AppProvider appProvider) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), + child: Text('主题颜色', style: Theme.of(context).textTheme.titleMedium), + ), + _buildDarkModeSection(context, appProvider), + _buildThemeColorList(context, appProvider), + ], + ); + } + + // 构建抽屉菜单项 + Widget _buildDrawerItem({ + required BuildContext context, + required IconData icon, + required String title, + required VoidCallback onTap, + }) { + return ListTile( + leading: Icon(icon, color: Theme.of(context).colorScheme.primary), + title: Text(title), + onTap: onTap, + ); + } + @override Widget build(BuildContext context) { + final appProvider = Provider.of(context); + return Drawer( child: ListView( padding: EdgeInsets.zero, children: [ // 抽屉头部 - buildDrawerHeader(), + buildDrawerHeader(context), // 菜单项 _buildDrawerItem( + context: context, icon: Icons.flash_on, title: '闪灵', onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).changeTab(0); + appProvider.changeTab(0); }, ), _buildDrawerItem( + context: context, icon: Icons.checklist, title: '待办事项', onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).changeTab(1); + appProvider.changeTab(1); }, ), const Divider(), _buildDrawerItem( + context: context, icon: Icons.analytics, title: '统计', onTap: () { @@ -73,6 +210,7 @@ class AppDrawer extends StatelessWidget { }, ), _buildDrawerItem( + context: context, icon: Icons.archive, title: '归档', onTap: () { @@ -83,15 +221,12 @@ class AppDrawer extends StatelessWidget { const Divider(), + _buildThemeSection(context, appProvider), + + const Divider(), + _buildDrawerItem( - icon: Icons.settings, - title: '设置', - onTap: () { - Navigator.pop(context); - // 这里可以导航到设置页面 - }, - ), - _buildDrawerItem( + context: context, icon: Icons.help, title: '帮助与反馈', onTap: () { @@ -103,17 +238,4 @@ class AppDrawer extends StatelessWidget { ), ); } - - // 构建抽屉菜单项 - Widget _buildDrawerItem({ - required IconData icon, - required String title, - required VoidCallback onTap, - }) { - return ListTile( - leading: Icon(icon, color: Colors.blue.shade600), - title: Text(title), - onTap: onTap, - ); - } } diff --git a/lib/layout/main_screen.dart b/lib/layout/main_screen.dart index ac6f6b1..01c6f33 100644 --- a/lib/layout/main_screen.dart +++ b/lib/layout/main_screen.dart @@ -28,20 +28,38 @@ class _MainScreenState extends State { return Scaffold( drawer: const AppDrawer(), appBar: AppBar( - title: Text(_getAppBarTitle(appProvider.currentIndex)), - backgroundColor: Colors.blue, - foregroundColor: Colors.white, + title: Text(_getAppBarTitle(appProvider.currentTab)), + backgroundColor: Theme.of(context).colorScheme.primary, + foregroundColor: Theme.of(context).colorScheme.onPrimary, elevation: 0, ), - body: _buildPage(appProvider.currentIndex), - bottomNavigationBar: BottomNavigationBar( - currentIndex: appProvider.currentIndex, - onTap: (index) => appProvider.changeTab(index), - type: BottomNavigationBarType.fixed, - backgroundColor: Colors.white, - items: navItems, + body: _buildPage(appProvider.currentTab), + bottomNavigationBar: Container( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Theme.of(context).colorScheme.shadow.withAlpha(20), + blurRadius: 8, + offset: const Offset(0, -2), + ), + ], + ), + child: BottomNavigationBar( + currentIndex: appProvider.currentTab, + onTap: (index) => appProvider.changeTab(index), + type: BottomNavigationBarType.fixed, + backgroundColor: Theme.of(context).colorScheme.surface, + selectedItemColor: Theme.of(context).colorScheme.primary, + unselectedItemColor: Theme.of(context).colorScheme.onSurface.withAlpha(120), + showSelectedLabels: true, + showUnselectedLabels: true, + items: navItems, + ), + ), + floatingActionButton: _buildFloatingButton( + context, + appProvider.currentTab, ), - floatingActionButton: _buildFloatingButton(appProvider.currentIndex), ); }, ); @@ -59,7 +77,7 @@ class _MainScreenState extends State { } } - Widget _buildFloatingButton(int index) { + Widget _buildFloatingButton(BuildContext context, int index) { return FloatingActionButton( onPressed: () => _onPressFloatingButton(index), backgroundColor: Colors.transparent, @@ -70,18 +88,7 @@ class _MainScreenState extends State { height: 50, decoration: BoxDecoration( shape: BoxShape.circle, - gradient: LinearGradient( - colors: [Colors.orange.shade300, Colors.orange.shade500], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - boxShadow: [ - BoxShadow( - color: Colors.orange.shade100, - blurRadius: 12, - offset: Offset(0, 6), - ), - ], + color: Theme.of(context).colorScheme.primary, ), child: Icon(Icons.add, color: Colors.white, size: 36), ), diff --git a/lib/main.dart b/lib/main.dart index a2f75a0..7196302 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,7 +11,7 @@ import 'layout/main_screen.dart'; import 'models/todo.dart'; import 'provider/todo_provider.dart'; -void main() async{ +void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化提醒服务 final notifyService = NotifyService(); @@ -50,22 +50,23 @@ class MyApp extends StatelessWidget { providers: [ ChangeNotifierProvider(create: (_) => AppProvider()), ChangeNotifierProvider(create: (_) => TodoProvider()), - ChangeNotifierProvider(create: (_) => FlispProvider()) + ChangeNotifierProvider(create: (_) => FlispProvider()), ], - child: MaterialApp( - title: '闪灵', - localizationsDelegates: [ - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate - ], - supportedLocales: [ - const Locale('zh'), - const Locale('zh', 'CN'), - ], - locale: Locale('zh', 'CN'), - theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true), - home: const MainScreen(), + child: Consumer( + builder: (context, appProvider, child) { + return MaterialApp( + title: '闪灵', + localizationsDelegates: [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [const Locale('zh'), const Locale('zh', 'CN')], + locale: Locale('zh', 'CN'), + theme: appProvider.currentThemeData, + home: const MainScreen(), + ); + }, ), ); } diff --git a/lib/pages/flisp_page.dart b/lib/pages/flisp_page.dart index 66eac02..fd754b7 100644 --- a/lib/pages/flisp_page.dart +++ b/lib/pages/flisp_page.dart @@ -40,11 +40,13 @@ class FlispPageState extends State { @override Widget build(BuildContext context) { - return buildBody( + return Padding( + padding: EdgeInsets.all(10), child: Column( children: [ buildStatsCard(_activeFlisps), buildTabs( + context: context, currentTab: _currentTab, onTabChanged: (value) { setState(() { @@ -53,15 +55,15 @@ class FlispPageState extends State { }, ), // 待办事项列表 - Expanded(child: _buildActiveFlispList()), + Expanded(child: _buildActiveFlispList(context)), ], ), ); } - Widget _buildActiveFlispList() { + Widget _buildActiveFlispList(BuildContext context) { return _activeFlisps.isEmpty - ? buildEmptyState() + ? buildEmptyState(context) : buildFlispList( context: context, flisps: _activeFlisps, diff --git a/lib/pages/todo_page.dart b/lib/pages/todo_page.dart index 00f2a1e..5739ef9 100644 --- a/lib/pages/todo_page.dart +++ b/lib/pages/todo_page.dart @@ -42,11 +42,13 @@ class TodoPageState extends State { @override Widget build(BuildContext context) { - return buildBody( + return Padding( + padding: EdgeInsets.all(10), child: Column( children: [ buildStatsCard(_todos), buildTabs( + context: context, currentTab: _currentTab, onTabChanged: (value) { setState(() { @@ -55,15 +57,15 @@ class TodoPageState extends State { }, ), // 待办事项列表 - Expanded(child: _buildActiveTodoList()), + Expanded(child: _buildActiveTodoList(context)), ], ), ); } - Widget _buildActiveTodoList() { + Widget _buildActiveTodoList(BuildContext context) { return _activeTodos.isEmpty - ? buildEmptyState(_currentTab) + ? buildEmptyState(context, _currentTab) : buildTodoList( todos: _activeTodos, onToggleTodo: (todo) { diff --git a/lib/provider/app_provider.dart b/lib/provider/app_provider.dart index af2369a..c0b785d 100644 --- a/lib/provider/app_provider.dart +++ b/lib/provider/app_provider.dart @@ -1,12 +1,188 @@ import 'package:flutter/material.dart'; -class AppProvider with ChangeNotifier { - int _currentIndex = 0; +class ThemeColor { + final String name; + final Color primaryColor; + final MaterialColor materialColor; - int get currentIndex => _currentIndex; + ThemeColor({ + required this.name, + required this.primaryColor, + required this.materialColor, + }); +} + +class AppProvider with ChangeNotifier { + int _currentTab = 0; + bool _isDarkMode = false; + ThemeColor _currentTheme = _defaultThemes[0]; + + // 预定义主题色 + static final List _defaultThemes = [ + ThemeColor( + name: '科技蓝', + primaryColor: Color(0xFF2563EB), + materialColor: MaterialColor(0xFF2563EB, { + 50: Color(0xFFDBEAFE), + 100: Color(0xFFBFDBFE), + 200: Color(0xFF93C5FD), + 300: Color(0xFF60A5FA), + 400: Color(0xFF3B82F6), + 500: Color(0xFF2563EB), + 600: Color(0xFF1D4ED8), + 700: Color(0xFF1E40AF), + 800: Color(0xFF1E3A8A), + 900: Color(0xFF1E3A8A), + }), + ), + ThemeColor( + name: '翡翠绿', + primaryColor: Color(0xFF10B981), + materialColor: MaterialColor(0xFF10B981, { + 50: Color(0xFFECFDF5), + 100: Color(0xFFD1FAE5), + 200: Color(0xFFA7F3D0), + 300: Color(0xFF6EE7B7), + 400: Color(0xFF34D399), + 500: Color(0xFF10B981), + 600: Color(0xFF059669), + 700: Color(0xFF047857), + 800: Color(0xFF065F46), + 900: Color(0xFF064E3B), + }), + ), + ThemeColor( + name: '活力橙', + primaryColor: Color(0xFFF59E0B), + materialColor: MaterialColor(0xFFF59E0B, { + 50: Color(0xFFFFFBEB), + 100: Color(0xFFFEF3C7), + 200: Color(0xFFFDE68A), + 300: Color(0xFFFCD34D), + 400: Color(0xFFFBBF24), + 500: Color(0xFFF59E0B), + 600: Color(0xFFD97706), + 700: Color(0xFFB45309), + 800: Color(0xFF92400E), + 900: Color(0xFF78350F), + }), + ), + ThemeColor( + name: '梦幻紫', + primaryColor: Color(0xFF8B5CF6), + materialColor: MaterialColor(0xFF8B5CF6, { + 50: Color(0xFFF5F3FF), + 100: Color(0xFFEDE9FE), + 200: Color(0xFFDDD6FE), + 300: Color(0xFFC4B5FD), + 400: Color(0xFFA78BFA), + 500: Color(0xFF8B5CF6), + 600: Color(0xFF7C3AED), + 700: Color(0xFF6D28D9), + 800: Color(0xFF5B21B6), + 900: Color(0xFF4C1D95), + }), + ), + ThemeColor( + name: '浪漫粉', + primaryColor: Color(0xFFEC4899), + materialColor: MaterialColor(0xFFEC4899, { + 50: Color(0xFFFDF2F8), + 100: Color(0xFFFCE7F3), + 200: Color(0xFFFBCFE8), + 300: Color(0xFFF9A8D4), + 400: Color(0xFFF472B6), + 500: Color(0xFFEC4899), + 600: Color(0xFFDB2777), + 700: Color(0xFFBE185D), + 800: Color(0xFF9D174D), + 900: Color(0xFF831843), + }), + ), + ThemeColor( + name: '清新青', + primaryColor: Color(0xFF06B6D4), + materialColor: MaterialColor(0xFF06B6D4, { + 50: Color(0xFFF0FDFA), + 100: Color(0xFFCCFBF1), + 200: Color(0xFF99F6E4), + 300: Color(0xFF5EEAD4), + 400: Color(0xFF2DD4BF), + 500: Color(0xFF06B6D4), + 600: Color(0xFF0891B2), + 700: Color(0xFF0E7490), + 800: Color(0xFF155E75), + 900: Color(0xFF164E63), + }), + ), + ThemeColor( + name: '深空蓝', + primaryColor: Color(0xFF1E40AF), + materialColor: MaterialColor(0xFF1E40AF, { + 50: Color(0xFFEFF6FF), + 100: Color(0xFFDBEAFE), + 200: Color(0xFFBFDBFE), + 300: Color(0xFF93C5FD), + 400: Color(0xFF60A5FA), + 500: Color(0xFF3B82F6), + 600: Color(0xFF2563EB), + 700: Color(0xFF1D4ED8), + 800: Color(0xFF1E40AF), + 900: Color(0xFF1E3A8A), + }), + ), + ThemeColor( + name: '落日红', + primaryColor: Color(0xFFEF4444), + materialColor: MaterialColor(0xFFEF4444, { + 50: Color(0xFFFEF2F2), + 100: Color(0xFFFEE2E2), + 200: Color(0xFFFECACA), + 300: Color(0xFFFCA5A5), + 400: Color(0xFFF87171), + 500: Color(0xFFEF4444), + 600: Color(0xFFDC2626), + 700: Color(0xFFB91C1C), + 800: Color(0xFF991B1B), + 900: Color(0xFF7F1D1D), + }), + ), + ]; + + int get currentTab => _currentTab; + + bool get isDarkMode => _isDarkMode; + + ThemeColor get currentTheme => _currentTheme; + + List get availableThemes => _defaultThemes; void changeTab(int index) { - _currentIndex = index; + _currentTab = index; notifyListeners(); } + + // 切换明暗模式 + void toggleDarkMode(bool value) { + _isDarkMode = value; + notifyListeners(); + } + + // 更改主题色 + void changeTheme(ThemeColor theme) { + _currentTheme = theme; + notifyListeners(); + } + + ThemeData get currentThemeData { + return ThemeData( + primarySwatch: _currentTheme.materialColor, + colorScheme: ColorScheme.fromSeed( + seedColor: _currentTheme.primaryColor, + brightness: _isDarkMode ? Brightness.dark : Brightness.light, + ), + useMaterial3: true, + fontFamily: 'CustomFont', + ); + } } diff --git a/lib/widgets/awesome_dialog.dart b/lib/widgets/awesome_dialog.dart index 06a398d..3cf2f61 100644 --- a/lib/widgets/awesome_dialog.dart +++ b/lib/widgets/awesome_dialog.dart @@ -25,7 +25,7 @@ void showAwesomeDialog({ onPressed: onOk, style: ElevatedButton.styleFrom( elevation: 0, - backgroundColor: Colors.orange, + backgroundColor: Theme.of(context).primaryColor, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), @@ -61,7 +61,7 @@ void showErrorDialog(BuildContext context, String message) { animType: AnimType.scale, title: message, btnOkText: "好的", - btnOkColor: Colors.green, + btnOkColor: Colors.red, btnOkOnPress: () {}, autoHide: Duration(seconds: 2), ).show(); diff --git a/lib/widgets/common.dart b/lib/widgets/common.dart index d8e2969..2aeb774 100644 --- a/lib/widgets/common.dart +++ b/lib/widgets/common.dart @@ -8,21 +8,25 @@ BoxDecoration buildBoxDecoration() { ); } -Container buildBody({Widget? child}) { - return Container( - width: double.infinity, - color: Colors.grey[50], - padding: EdgeInsets.all(8), - child: child, - ); -} +class BuildCard extends StatelessWidget { + final Widget? child; -Container buildCard({Widget? child}) { - return Container( - decoration: buildBoxDecoration(), - padding: EdgeInsets.all(10), - child: child, - ); + const BuildCard({super.key, this.child}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Container( + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: colors.outline.withAlpha(50), width: 1), + ), + padding: const EdgeInsets.all(16), + child: child, + ); + } } void buildModalBottom({ diff --git a/lib/widgets/flisp_widget.dart b/lib/widgets/flisp_widget.dart index 145f7d1..02b839b 100644 --- a/lib/widgets/flisp_widget.dart +++ b/lib/widgets/flisp_widget.dart @@ -11,7 +11,7 @@ Widget buildStatsCard(List flisps) { int workCount = flisps.where((flisp) => flisp.tag == FlispTag.work).length; int studyCount = flisps.where((flisp) => flisp.tag == FlispTag.study).length; - return buildCard( + return BuildCard( child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -42,6 +42,7 @@ Widget _buildStatItem(String label, int count, Color color) { } Widget buildTabs({ + required BuildContext context, required FlispTab currentTab, required ValueChanged onTabChanged, }) { @@ -53,7 +54,7 @@ Widget buildTabs({ initialLabelIndex: FlispTab.values.indexOf(currentTab), totalSwitches: FlispTab.values.length, labels: FlispTab.values.map((e) => e.label).toList(), - activeBgColor: [Colors.orange.shade600], + activeBgColor: [Theme.of(context).colorScheme.primary], activeFgColor: Colors.white, inactiveBgColor: Colors.grey.shade200, inactiveFgColor: Colors.grey.shade700, @@ -89,11 +90,15 @@ Widget buildFlispList({ ); } -Widget _buildFlispContent(Flisp flisp) { +Widget _buildFlispContent(BuildContext context, Flisp flisp) { return RichText( text: TextSpan( text: flisp.content, - style: const TextStyle(color: Colors.black87, fontSize: 16), + style: TextStyle( + fontFamily: 'CustomFont', + color: Theme.of(context).colorScheme.onSurface, + fontSize: 16, + ), ), ); } @@ -281,15 +286,13 @@ Widget _buildFlispItem({ onDismissed: (direction) { onDelete(flisp); }, - child: Container( - decoration: buildBoxDecoration(), - padding: EdgeInsets.all(16), + child: BuildCard( child: InkWell( onTap: () => onEdit(flisp), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildFlispContent(flisp), + _buildFlispContent(context, flisp), const SizedBox(height: 8), if (hasImage) buildFlispImage(flisp: flisp, showDelete: false), const SizedBox(height: 4), @@ -337,16 +340,19 @@ Widget _buildDismissBackground() { } // 空状态 -Widget buildEmptyState() { +Widget buildEmptyState(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.flash_on, size: 80, color: Colors.orange.shade600), + Icon(Icons.flash_on, size: 80, color: colors.primary), + const SizedBox(height: 16), Text( - '📝 还没有闪灵\n点击➕号添加第一个灵感吧~', + '📝 还没有该类别闪灵\n点击➕号添加第一个灵感吧~', textAlign: TextAlign.center, - style: TextStyle(color: Colors.orange.shade600), + style: TextStyle(color: colors.onSurface, fontSize: 16), ), ], ), diff --git a/lib/widgets/todo_form.dart b/lib/widgets/todo_form.dart index 1dcdabe..eac3ae7 100644 --- a/lib/widgets/todo_form.dart +++ b/lib/widgets/todo_form.dart @@ -38,7 +38,7 @@ class _TodoFormState extends State { children: [ Icon( widget.isEditing ? Icons.edit_note : Icons.add_task, - color: Colors.orange, + color: Theme.of(context).primaryColor, size: 24, ), SizedBox(width: 8), @@ -47,7 +47,7 @@ class _TodoFormState extends State { style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, - color: Colors.orange, + color: Theme.of(context).primaryColor, ), ), ], diff --git a/lib/widgets/todo_widget.dart b/lib/widgets/todo_widget.dart index ef9b9b4..6f68fc8 100644 --- a/lib/widgets/todo_widget.dart +++ b/lib/widgets/todo_widget.dart @@ -13,7 +13,7 @@ Widget buildStatsCard(List todos) { int completedCount = todos.where((todo) => todo.isCompleted).length; - return buildCard( + return BuildCard( child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -44,6 +44,7 @@ Widget _buildStatItem(String label, int count, Color color) { // Tab页 Widget buildTabs({ + required BuildContext context, required TodoTab currentTab, required ValueChanged onTabChanged, }) { @@ -55,7 +56,7 @@ Widget buildTabs({ initialLabelIndex: TodoTab.values.indexOf(currentTab), totalSwitches: TodoTab.values.length, labels: TodoTab.values.map((e) => e.label).toList(), - activeBgColor: [Colors.orange.shade600], + activeBgColor: [Theme.of(context).colorScheme.primary], activeFgColor: Colors.white, inactiveBgColor: Colors.grey.shade200, inactiveFgColor: Colors.grey.shade700, @@ -94,7 +95,7 @@ Widget _buildTodoItem({ required ValueChanged onToggle, required ValueChanged onEdit, }) { - return buildCard( + return BuildCard( child: ListTile( contentPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 0), leading: SizedBox( @@ -267,7 +268,7 @@ Widget _buildPriorityBadge(TodoPriority priority) { } // 空状态 -Widget buildEmptyState(TodoTab tab) { +Widget buildEmptyState(BuildContext context, TodoTab tab) { final messages = { TodoTab.all: '📝 还没有待办事项\n点击➕号添加第一个任务吧~', TodoTab.active: '🎯 没有待完成的任务\n享受轻松时光吧!✨', @@ -275,15 +276,18 @@ Widget buildEmptyState(TodoTab tab) { TodoTab.today: '📅 今天没有安排任务\n好好放松一下吧~😊', }; + final colors = Theme.of(context).colorScheme; + return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.checklist, size: 80, color: Colors.orange.shade600), + Icon(Icons.checklist, size: 80, color: colors.primary), + const SizedBox(height: 16), Text( messages[tab] ?? '暂无数据', textAlign: TextAlign.center, - style: TextStyle(color: Colors.orange.shade600), + style: TextStyle(color: colors.onSurface, fontSize: 16), ), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index d05e74d..9399e0f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,32 +1,12 @@ name: flisp_app description: "闪灵" -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. version: 1.0.0+1 environment: sdk: ^3.7.0 -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter @@ -70,52 +50,11 @@ dev_dependencies: sdk: flutter hive_generator: ^2.0.1 build_runner: ^2.4.6 - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. flutter_lints: ^5.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/to/resolution-aware-images - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/to/asset-from-package - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/to/font-from-package + fonts: + - family: CustomFont + fonts: + - asset: fonts/custom.ttf