diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 6ae2428..9e9871c 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -19,7 +19,7 @@ if (keystorePropertiesFile.exists()) { android { namespace = "com.cxx.flisp_app" compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion + ndkVersion = "27.0.12077973" compileOptions { sourceCompatibility = JavaVersion.VERSION_11 @@ -46,7 +46,7 @@ android { // 签名配置 signingConfigs { - create("release") { + create("sigin") { if (keystorePropertiesFile.exists()) { keyAlias = keystoreProperties.getProperty("keyAlias") keyPassword = keystoreProperties.getProperty("keyPassword") @@ -57,10 +57,18 @@ android { } buildTypes { - release { - // 修改这里:使用发布签名配置 + debug { signingConfig = if (keystorePropertiesFile.exists()) { - signingConfigs.getByName("release") + signingConfigs.getByName("sigin") + } else { + signingConfigs.getByName("debug") + } + } + + release { + // 使用发布签名配置 + signingConfig = if (keystorePropertiesFile.exists()) { + signingConfigs.getByName("sigin") } else { signingConfigs.getByName("debug") } diff --git a/lib/layout/app_drawer.dart b/lib/layout/app_drawer.dart index 22a98c9..5d7c30c 100644 --- a/lib/layout/app_drawer.dart +++ b/lib/layout/app_drawer.dart @@ -1,4 +1,5 @@ import 'package:flisp_app/provider/app_provider.dart'; +import 'package:flisp_app/utils/theme_utils.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -57,88 +58,6 @@ class AppDrawer extends StatelessWidget { ); } - 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, @@ -148,7 +67,7 @@ class AppDrawer extends StatelessWidget { child: Text('主题颜色', style: Theme.of(context).textTheme.titleMedium), ), _buildDarkModeSection(context, appProvider), - _buildThemeColorList(context, appProvider), + buildThemeColorList(context, appProvider), ], ); } @@ -178,49 +97,6 @@ class AppDrawer extends StatelessWidget { // 抽屉头部 buildDrawerHeader(context), - // 菜单项 - _buildDrawerItem( - context: context, - icon: Icons.flash_on, - title: '闪灵', - onTap: () { - Navigator.pop(context); - appProvider.changeTab(0); - }, - ), - _buildDrawerItem( - context: context, - icon: Icons.checklist, - title: '待办事项', - onTap: () { - Navigator.pop(context); - appProvider.changeTab(1); - }, - ), - - const Divider(), - - _buildDrawerItem( - context: context, - icon: Icons.analytics, - title: '统计', - onTap: () { - Navigator.pop(context); - // 这里可以导航到统计页面 - }, - ), - _buildDrawerItem( - context: context, - icon: Icons.archive, - title: '归档', - onTap: () { - Navigator.pop(context); - // 这里可以导航到归档页面 - }, - ), - - const Divider(), - _buildThemeSection(context, appProvider), const Divider(), diff --git a/lib/pages/flisp_page.dart b/lib/pages/flisp_page.dart index fd754b7..8b06038 100644 --- a/lib/pages/flisp_page.dart +++ b/lib/pages/flisp_page.dart @@ -44,7 +44,6 @@ class FlispPageState extends State { padding: EdgeInsets.all(10), child: Column( children: [ - buildStatsCard(_activeFlisps), buildTabs( context: context, currentTab: _currentTab, diff --git a/lib/pages/todo_page.dart b/lib/pages/todo_page.dart index 5739ef9..f53072d 100644 --- a/lib/pages/todo_page.dart +++ b/lib/pages/todo_page.dart @@ -46,7 +46,6 @@ class TodoPageState extends State { padding: EdgeInsets.all(10), child: Column( children: [ - buildStatsCard(_todos), buildTabs( context: context, currentTab: _currentTab, @@ -67,6 +66,7 @@ class TodoPageState extends State { return _activeTodos.isEmpty ? buildEmptyState(context, _currentTab) : buildTodoList( + context: context, todos: _activeTodos, onToggleTodo: (todo) { setState(() { @@ -76,6 +76,9 @@ class TodoPageState extends State { onEditTodo: (todo) { _showDialog(true, todo); }, + onDelete: (todo) { + _deleteTodo(todo); + }, ); } @@ -149,4 +152,19 @@ class TodoPageState extends State { showErrorDialog(context, isEditing ? '更新失败' : '添加失败'); } } + + void _deleteTodo(Todo todo) async { + await notifyService.cancelNotification(todo.id); + bool isSuccess = await todoService.deleteTodo(todo); + + setState(() { + _todos = todoService.getAllTodos(); + }); + + if (isSuccess) { + showSuccessDialog(context, '删除成功'); + } else { + showErrorDialog(context, '删除失败'); + } + } } diff --git a/lib/provider/app_provider.dart b/lib/provider/app_provider.dart index c0b785d..31b1728 100644 --- a/lib/provider/app_provider.dart +++ b/lib/provider/app_provider.dart @@ -1,153 +1,54 @@ +import 'package:flisp_app/utils/theme_utils.dart'; import 'package:flutter/material.dart'; - -class ThemeColor { - final String name; - final Color primaryColor; - final MaterialColor materialColor; - - ThemeColor({ - required this.name, - required this.primaryColor, - required this.materialColor, - }); -} +import 'package:shared_preferences/shared_preferences.dart'; class AppProvider with ChangeNotifier { + static const String _themeKey = 'selected_theme'; + static const String _darkModeKey = 'is_dark_mode'; + int _currentTab = 0; bool _isDarkMode = false; - ThemeColor _currentTheme = _defaultThemes[0]; + ThemeColor _currentTheme = defaultThemes[0]; + late SharedPreferences _prefs; + bool _isInitialized = false; - // 预定义主题色 - 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), - }), - ), - ]; + AppProvider() { + _initPreferences(); + } + + // 初始化 SharedPreferences + Future _initPreferences() async { + _prefs = await SharedPreferences.getInstance(); + _loadPreferences(); + _isInitialized = true; + notifyListeners(); + } + + // 加载存储的设置 + void _loadPreferences() { + _isDarkMode = _prefs.getBool(_darkModeKey) ?? false; + + // 加载主题色 + final themeName = _prefs.getString(_themeKey); + if (themeName != null) { + // 根据主题名称查找对应的主题 + final savedTheme = defaultThemes.firstWhere( + (theme) => theme.name == themeName, + orElse: () => defaultThemes[0], + ); + _currentTheme = savedTheme; + } + } + + // 保存主题色 + Future _saveTheme() async { + await _prefs.setString(_themeKey, _currentTheme.name); + } + + // 保存暗黑模式 + Future _saveDarkMode() async { + await _prefs.setBool(_darkModeKey, _isDarkMode); + } int get currentTab => _currentTab; @@ -155,7 +56,9 @@ class AppProvider with ChangeNotifier { ThemeColor get currentTheme => _currentTheme; - List get availableThemes => _defaultThemes; + List get availableThemes => defaultThemes; + + bool get isInitialized => _isInitialized; void changeTab(int index) { _currentTab = index; @@ -165,12 +68,14 @@ class AppProvider with ChangeNotifier { // 切换明暗模式 void toggleDarkMode(bool value) { _isDarkMode = value; + _saveDarkMode(); notifyListeners(); } // 更改主题色 void changeTheme(ThemeColor theme) { _currentTheme = theme; + _saveTheme(); notifyListeners(); } @@ -185,4 +90,4 @@ class AppProvider with ChangeNotifier { fontFamily: 'CustomFont', ); } -} +} \ No newline at end of file diff --git a/lib/utils/theme_utils.dart b/lib/utils/theme_utils.dart new file mode 100644 index 0000000..bbcbd8c --- /dev/null +++ b/lib/utils/theme_utils.dart @@ -0,0 +1,229 @@ +import 'dart:ui'; + +import 'package:flisp_app/provider/app_provider.dart'; +import 'package:flutter/material.dart'; + +class ThemeColor { + final String name; + final Color primaryColor; + final MaterialColor materialColor; + + ThemeColor({ + required this.name, + required this.primaryColor, + required this.materialColor, + }); +} + +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), + }), + ), +]; + +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, + ), + ), + ], + ), + ), + ); +} diff --git a/lib/widgets/common.dart b/lib/widgets/common.dart index 3603cc0..d0f1b2b 100644 --- a/lib/widgets/common.dart +++ b/lib/widgets/common.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:toggle_switch/toggle_switch.dart'; BoxDecoration buildBoxDecoration() { return BoxDecoration( @@ -8,6 +9,7 @@ BoxDecoration buildBoxDecoration() { ); } +// 卡片 class BuildCard extends StatelessWidget { final Widget? child; @@ -29,6 +31,7 @@ class BuildCard extends StatelessWidget { } } +// 底部弹出 void buildModalBottom({ required BuildContext context, required String title, @@ -113,3 +116,86 @@ Widget buildModalBottomBody(BuildContext context, String title, Widget body) { ], ); } + +// 滑动删除 +Widget buildDismissible({ + required BuildContext context, + required Object id, + required Widget child, + required VoidCallback onDelete, +}) { + return Dismissible( + key: ValueKey(id), + direction: DismissDirection.endToStart, + background: _buildDismissBackground(), + confirmDismiss: (direction) async { + // 这里实现二次确认 + return await _showDeleteConfirmationDialog(context); + }, + onDismissed: (direction) { + onDelete(); + }, + child: child, + ); +} + +// 确认对话框 +Future _showDeleteConfirmationDialog(BuildContext context) async { + return showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('确认删除'), + backgroundColor: Colors.white, + content: const Text('确定要删除这个项目吗?'), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('取消'), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(true), + child: const Text('删除', style: TextStyle(color: Colors.red)), + ), + ], + ); + }, + ); +} + +Widget _buildDismissBackground() { + return Container( + color: Colors.red, + alignment: Alignment.centerRight, + padding: const EdgeInsets.only(right: 20), + child: const Icon(Icons.delete, color: Colors.white, size: 24), + ); +} + +// toggle切换 +Widget buildToggleSwitch({ + required BuildContext context, + required T currentTab, + required List tabValues, + required List labels, + required ValueChanged onTabChanged, +}) { + return ToggleSwitch( + minWidth: 90.0, + minHeight: 40.0, + initialLabelIndex: tabValues.indexOf(currentTab), + totalSwitches: tabValues.length, + labels: labels, + activeBgColor: [Theme.of(context).colorScheme.primary], + activeFgColor: Colors.white, + inactiveBgColor: Colors.grey.shade200, + inactiveFgColor: Colors.grey.shade700, + cornerRadius: 12.0, + customTextStyles: [TextStyle(fontSize: 12, fontWeight: FontWeight.w500)], + onToggle: (index) { + if (index != null && index < tabValues.length) { + onTabChanged(tabValues[index]); + } + }, + ); +} diff --git a/lib/widgets/flisp_form.dart b/lib/widgets/flisp_form.dart index b2290e6..8319c87 100644 --- a/lib/widgets/flisp_form.dart +++ b/lib/widgets/flisp_form.dart @@ -79,6 +79,7 @@ class _FlispFormState extends State { }, decoration: InputDecoration( hintText: '记录你的灵感瞬间...', + hintStyle: TextStyle(color: Colors.grey), counterText: '', suffixText: '${provider.formItem.content.length}/$maxContentCount', border: OutlineInputBorder( diff --git a/lib/widgets/flisp_widget.dart b/lib/widgets/flisp_widget.dart index 02b839b..086e4aa 100644 --- a/lib/widgets/flisp_widget.dart +++ b/lib/widgets/flisp_widget.dart @@ -48,23 +48,12 @@ Widget buildTabs({ }) { return Container( padding: EdgeInsets.all(8), - child: ToggleSwitch( - minWidth: 90.0, - minHeight: 40.0, - initialLabelIndex: FlispTab.values.indexOf(currentTab), - totalSwitches: FlispTab.values.length, + child: buildToggleSwitch( + context: context, + currentTab: currentTab, + tabValues: FlispTab.values, labels: FlispTab.values.map((e) => e.label).toList(), - activeBgColor: [Theme.of(context).colorScheme.primary], - activeFgColor: Colors.white, - inactiveBgColor: Colors.grey.shade200, - inactiveFgColor: Colors.grey.shade700, - cornerRadius: 12.0, - customTextStyles: [TextStyle(fontSize: 12, fontWeight: FontWeight.w500)], - onToggle: (index) { - if (index != null) { - onTabChanged(FlispTab.values[index]); - } - }, + onTabChanged: onTabChanged, ), ); } @@ -275,17 +264,10 @@ Widget _buildFlispItem({ final hasImage = flisp.imageUrl.isNotEmpty; final hasVideo = flisp.videoUrl.isNotEmpty; - return Dismissible( - key: ValueKey(flisp.id), - direction: DismissDirection.endToStart, - background: _buildDismissBackground(), - confirmDismiss: (direction) async { - // 这里实现二次确认 - return await _showDeleteConfirmationDialog(context); - }, - onDismissed: (direction) { - onDelete(flisp); - }, + return buildDismissible( + context: context, + id: flisp.id, + onDelete: () => onDelete(flisp), child: BuildCard( child: InkWell( onTap: () => onEdit(flisp), @@ -306,39 +288,6 @@ Widget _buildFlispItem({ ); } -// 确认对话框 -Future _showDeleteConfirmationDialog(BuildContext context) async { - return showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: const Text('确认删除'), - backgroundColor: Colors.white, - content: const Text('确定要删除这个项目吗?'), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(false), - child: const Text('取消'), - ), - TextButton( - onPressed: () => Navigator.of(context).pop(true), - child: const Text('删除', style: TextStyle(color: Colors.red)), - ), - ], - ); - }, - ); -} - -Widget _buildDismissBackground() { - return Container( - color: Colors.red, - alignment: Alignment.centerRight, - padding: const EdgeInsets.only(right: 20), - child: const Icon(Icons.delete, color: Colors.white, size: 24), - ); -} - // 空状态 Widget buildEmptyState(BuildContext context) { final colors = Theme.of(context).colorScheme; diff --git a/lib/widgets/todo_form.dart b/lib/widgets/todo_form.dart index abcefe4..5d0fccd 100644 --- a/lib/widgets/todo_form.dart +++ b/lib/widgets/todo_form.dart @@ -82,6 +82,7 @@ class _TodoFormState extends State { ), ), hintText: '请输入待办事项标题...', + hintStyle: TextStyle(color: Colors.grey), counterText: '', suffixText: '${provider.formItem.title.length}/$maxTitleCount', border: OutlineInputBorder( @@ -126,6 +127,7 @@ class _TodoFormState extends State { decoration: InputDecoration( labelText: '内容', hintText: '请输入待办事项内容...', + hintStyle: TextStyle(color: Colors.grey), counterText: '', suffixText: '${provider.formItem.content.length}/$maxContentCount', border: OutlineInputBorder( diff --git a/lib/widgets/todo_widget.dart b/lib/widgets/todo_widget.dart index 6f68fc8..46b323a 100644 --- a/lib/widgets/todo_widget.dart +++ b/lib/widgets/todo_widget.dart @@ -50,31 +50,22 @@ Widget buildTabs({ }) { return Container( padding: EdgeInsets.all(8), - child: ToggleSwitch( - minWidth: 90.0, - minHeight: 40.0, - initialLabelIndex: TodoTab.values.indexOf(currentTab), - totalSwitches: TodoTab.values.length, + child: buildToggleSwitch( + context: context, + currentTab: currentTab, + tabValues: TodoTab.values, labels: TodoTab.values.map((e) => e.label).toList(), - activeBgColor: [Theme.of(context).colorScheme.primary], - activeFgColor: Colors.white, - inactiveBgColor: Colors.grey.shade200, - inactiveFgColor: Colors.grey.shade700, - cornerRadius: 12.0, - customTextStyles: [TextStyle(fontSize: 12, fontWeight: FontWeight.w500)], - onToggle: (index) { - if (index != null) { - onTabChanged(TodoTab.values[index]); - } - }, + onTabChanged: onTabChanged, ), ); } Widget buildTodoList({ + required BuildContext context, required List todos, required ValueChanged onToggleTodo, required ValueChanged onEditTodo, + required ValueChanged onDelete, }) { return ListView.separated( itemCount: todos.length, @@ -82,35 +73,44 @@ Widget buildTodoList({ itemBuilder: (context, index) { final todo = todos[index]; return _buildTodoItem( + context: context, todo: todo, onToggle: onToggleTodo, onEdit: onEditTodo, + onDelete: onDelete, ); }, ); } Widget _buildTodoItem({ + required BuildContext context, required Todo todo, required ValueChanged onToggle, required ValueChanged onEdit, + required ValueChanged onDelete, }) { - return BuildCard( - child: ListTile( - contentPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 0), - leading: SizedBox( - width: 24, - child: Checkbox( - value: todo.isCompleted, - onChanged: (value) => onToggle(todo), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + return buildDismissible( + context: context, + id: todo.id, + onDelete: () => onDelete(todo), + child: BuildCard( + child: ListTile( + contentPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 0), + leading: SizedBox( + width: 24, + child: Checkbox( + value: todo.isCompleted, + onChanged: (value) => onToggle(todo), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), ), + title: _buildTodoTitle(todo), + subtitle: _buildTodoSubtitle(todo), + trailing: _buildPriorityBadge(todo.priority), + onTap: () => onEdit(todo), + // onLongPress: () => onShowOptions(todo), ), - title: _buildTodoTitle(todo), - subtitle: _buildTodoSubtitle(todo), - trailing: _buildPriorityBadge(todo.priority), - onTap: () => onEdit(todo), - // onLongPress: () => onShowOptions(todo), ), ); }