diff --git a/lib/layout/main_screen.dart b/lib/layout/main_screen.dart index f4df9f9..ac6f6b1 100644 --- a/lib/layout/main_screen.dart +++ b/lib/layout/main_screen.dart @@ -1,5 +1,5 @@ import 'package:flisp_app/layout/app_drawer.dart'; -import 'package:flisp_app/pages/flash_page.dart'; +import 'package:flisp_app/pages/flisp_page.dart'; import 'package:flisp_app/pages/todo_page.dart'; import 'package:flisp_app/provider/app_provider.dart'; import 'package:flutter/material.dart'; @@ -13,11 +13,12 @@ class MainScreen extends StatefulWidget { } class _MainScreenState extends State { + final GlobalKey _flispPageKey = GlobalKey(); final GlobalKey _todoPageKey = GlobalKey(); List navItems = [ BottomNavigationBarItem(icon: Icon(Icons.flash_on), label: '闪灵'), - BottomNavigationBarItem(icon: Icon(Icons.checklist), label: '待办') + BottomNavigationBarItem(icon: Icon(Icons.checklist), label: '待办'), ]; @override @@ -47,7 +48,11 @@ class _MainScreenState extends State { } void _onPressFloatingButton(int index) { - if (index == 1) { + if (index == 0) { + if (_flispPageKey.currentState != null) { + _flispPageKey.currentState!.showAddDialog(); + } + } else if (index == 1) { if (_todoPageKey.currentState != null) { _todoPageKey.currentState!.showAddDialog(); } @@ -86,11 +91,11 @@ class _MainScreenState extends State { Widget _buildPage(int index) { switch (index) { case 0: - return const FlashPage(); + return FlispPage(key: _flispPageKey); case 1: return TodoPage(key: _todoPageKey); default: - return const FlashPage(); + return FlispPage(key: _flispPageKey); } } diff --git a/lib/main.dart b/lib/main.dart index 5de202f..1fb9000 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,6 @@ +import 'package:flisp_app/models/flisp.dart'; import 'package:flisp_app/provider/app_provider.dart'; +import 'package:flisp_app/provider/flisp_provider.dart'; import 'package:flisp_app/utils/notify_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; @@ -21,15 +23,19 @@ void main() async{ // 注册适配器 Hive.registerAdapter(TodoAdapter()); + Hive.registerAdapter(FlispAdapter()); - // 打开Box - if (Hive.isBoxOpen('todos')) { - await Hive.box('todos').close(); - } - await Hive.deleteBoxFromDisk('todos'); + // // 打开Box + // if (Hive.isBoxOpen('flisps')) { + // await Hive.box('flisps').close(); + // } + // await Hive.deleteBoxFromDisk('flisps'); final todosBox = await Hive.openBox('todos'); - todosBox.clear(); + // todosBox.clear(); + + final flispBox = await Hive.openBox('flisps'); + // flispBox.clear(); // notifyService.cancelAllNotifications(); @@ -44,7 +50,8 @@ class MyApp extends StatelessWidget { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => AppProvider()), - ChangeNotifierProvider(create: (_) => TodoProvider()) + ChangeNotifierProvider(create: (_) => TodoProvider()), + ChangeNotifierProvider(create: (_) => FlispProvider()) ], child: MaterialApp( title: '闪灵', diff --git a/lib/models/flisp.dart b/lib/models/flisp.dart new file mode 100644 index 0000000..74b4ac6 --- /dev/null +++ b/lib/models/flisp.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; +import 'package:hive/hive.dart'; + +// flutter packages pub run build_runner build +part 'flisp.g.dart'; + +@HiveType(typeId: 1) +class Flisp extends HiveObject { + @HiveField(0) + late int id; + + @HiveField(1) + late String content; + + @HiveField(2) + late int tagIndex; + + @HiveField(3) + late String imageUrl; + + @HiveField(4) + late String videoUrl; + + @HiveField(5) + late DateTime createTime; + + @HiveField(6) + late DateTime updateTime; + + FlispTag get tag => FlispTag.values[tagIndex]; + + set tag(FlispTag value) => tagIndex = value.index; + + Flisp({ + int? id, + required this.content, + FlispTag tag = FlispTag.study, + required this.imageUrl, + required this.videoUrl, + DateTime? createTime, + DateTime? updateTime, + }) { + // 简单时间戳ID + this.id = id ?? DateTime.now().millisecondsSinceEpoch ~/ 1000; + this.content = content; + this.tag = tag; + this.imageUrl = imageUrl; + this.videoUrl = videoUrl; + this.createTime = createTime ?? DateTime.now(); + this.updateTime = updateTime ?? DateTime.now(); + } + + static Flisp getEmpty() { + return Flisp( + id: DateTime.now().millisecondsSinceEpoch ~/ 1000, + content: '', + tag: FlispTag.study, + imageUrl: '', + videoUrl: '', + ); + } +} + +enum FlispTag { + study('学习', Color(0xFF9C27B0), Icons.school), + work('工作', Color(0xFF2196F3), Icons.work), + life('生活', Color(0xFF4CAF50), Icons.home); + + final String label; + final Color color; + final IconData icon; + + const FlispTag(this.label, this.color, this.icon); +} + +enum FlispTab { + all('全部'), + life('生活'), + work('工作'), + study('学习'); + + final String label; + + const FlispTab(this.label); +} \ No newline at end of file diff --git a/lib/models/flisp.g.dart b/lib/models/flisp.g.dart new file mode 100644 index 0000000..205f405 --- /dev/null +++ b/lib/models/flisp.g.dart @@ -0,0 +1,58 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'flisp.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class FlispAdapter extends TypeAdapter { + @override + final int typeId = 1; + + @override + Flisp read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return Flisp( + id: fields[0] as int?, + content: fields[1] as String, + imageUrl: fields[3] as String, + videoUrl: fields[4] as String, + createTime: fields[5] as DateTime?, + updateTime: fields[6] as DateTime?, + )..tagIndex = fields[2] as int; + } + + @override + void write(BinaryWriter writer, Flisp obj) { + writer + ..writeByte(7) + ..writeByte(0) + ..write(obj.id) + ..writeByte(1) + ..write(obj.content) + ..writeByte(2) + ..write(obj.tagIndex) + ..writeByte(3) + ..write(obj.imageUrl) + ..writeByte(4) + ..write(obj.videoUrl) + ..writeByte(5) + ..write(obj.createTime) + ..writeByte(6) + ..write(obj.updateTime); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is FlispAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/pages/flash_page.dart b/lib/pages/flash_page.dart deleted file mode 100644 index 092ccd5..0000000 --- a/lib/pages/flash_page.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flisp_app/widgets/common.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; - -class FlashPage extends StatefulWidget { - const FlashPage({super.key}); - - @override - _FlashPageState createState() => _FlashPageState(); -} - -class _FlashPageState extends State { - late QuillController _controller; - - @override - void initState() { - super.initState(); - _controller = QuillController.basic(); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - @override - Widget build(BuildContext context) { - return buildBody( - child: Column( - children: [ - QuillSimpleToolbar( - controller: _controller, - config: const QuillSimpleToolbarConfig(), - ), - Expanded( - child: QuillEditor.basic( - controller: _controller, - config: const QuillEditorConfig(), - ), - ), - ], - ), - ); - } -} \ No newline at end of file diff --git a/lib/pages/flisp_page.dart b/lib/pages/flisp_page.dart new file mode 100644 index 0000000..2968c47 --- /dev/null +++ b/lib/pages/flisp_page.dart @@ -0,0 +1,123 @@ +import 'package:flisp_app/models/flisp.dart'; +import 'package:flisp_app/provider/flisp_provider.dart'; +import 'package:flisp_app/service/flisp_service.dart'; +import 'package:flisp_app/utils/flisp_utils.dart'; +import 'package:flisp_app/widgets/awesome_dialog.dart'; +import 'package:flisp_app/widgets/flisp_form.dart'; +import 'package:flisp_app/widgets/flisp_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:provider/provider.dart'; +import 'package:flisp_app/widgets/common.dart'; + +class FlispPage extends StatefulWidget { + final VoidCallback? onAddPressed; + + const FlispPage({super.key, this.onAddPressed}); + + @override + State createState() => FlispPageState(); +} + +class FlispPageState extends State { + final FlispService flispService = FlispService(); + + late List _flisps; + FlispTab _currentTab = FlispTab.all; + + // 获取过滤后的待办事项 + List get _activeFlisps => getActiveFlisps(_currentTab, _flisps); + + void showAddDialog() { + _showDialog(false, null); + } + + @override + void initState() { + super.initState(); + _flisps = flispService.getAllFlisps(); + } + + @override + Widget build(BuildContext context) { + return buildBody( + child: Column( + children: [ + // 选项卡 + buildTabs( + currentTab: _currentTab, + onTabChanged: (value) { + setState(() { + _currentTab = value; + }); + }, + ), + // 待办事项列表 + Expanded(child: _buildActiveFlispList()), + ], + ), + ); + } + + Widget _buildActiveFlispList() { + return _activeFlisps.isEmpty + ? buildEmptyState() + : buildFlispList( + flisps: _activeFlisps, + onEdit: (flisp) { + _showDialog(true, flisp); + }, + ); + } + + // 显示对话框 + void _showDialog(bool isEditing, Flisp? flisp) { + final flispProvider = Provider.of(context, listen: false); + + if (isEditing) { + flispProvider.initForm(flisp!); + } else { + flispProvider.resetForm(); + } + + final formKey = GlobalKey(); + + showAwesomeDialog( + context: context, + body: FlispForm( + formKey: formKey, + isEditing: isEditing, + initialFlisp: flisp, + ), + onOk: () { + if (formKey.currentState!.saveAndValidate()) { + Navigator.of(context).pop(); + _saveFlisp(isEditing, flispProvider.formItem); + } + }, + onCancel: () { + flispProvider.resetForm(); + }, + ); + } + + // 保存待办事项 + void _saveFlisp(bool isEditing, Flisp flisp) async { + late bool isSuccess; + if (isEditing) { + isSuccess = await flispService.updateFlisp(flisp); + } else { + isSuccess = await flispService.addFlisp(flisp); + } + + setState(() { + _flisps = flispService.getAllFlisps(); + }); + + if (isSuccess) { + showSuccessDialog(context, isEditing ? '更新成功' : '添加成功'); + } else { + showErrorDialog(context, isEditing ? '更新失败' : '添加失败'); + } + } +} diff --git a/lib/provider/flisp_provider.dart b/lib/provider/flisp_provider.dart new file mode 100644 index 0000000..cab6118 --- /dev/null +++ b/lib/provider/flisp_provider.dart @@ -0,0 +1,18 @@ +import 'package:flisp_app/models/flisp.dart'; +import 'package:flutter/material.dart'; + +class FlispProvider with ChangeNotifier { + late Flisp _formItem; + + Flisp get formItem => _formItem; + + void resetForm() { + _formItem = Flisp.getEmpty(); + notifyListeners(); + } + + void initForm(Flisp flisp) { + _formItem = flisp; + notifyListeners(); + } +} diff --git a/lib/service/flisp_service.dart b/lib/service/flisp_service.dart new file mode 100644 index 0000000..11f9688 --- /dev/null +++ b/lib/service/flisp_service.dart @@ -0,0 +1,39 @@ +import 'package:flisp_app/models/flisp.dart'; +import 'package:hive_flutter/hive_flutter.dart'; + +class FlispService { + static const String boxName = 'flisps'; + + Box get box => Hive.box(boxName); + + Future addFlisp(Flisp flisp) async { + try { + await box.add(flisp); + return true; + } catch (e) { + return false; + } + } + + List getAllFlisps() { + return box.values.toList(); + } + + Future updateFlisp(Flisp flisp) async { + try { + await flisp.save(); + return true; + } catch (e) { + return false; + } + } + + Future deleteFlisp(Flisp flisp) async { + try { + await flisp.delete(); + return true; + } catch (e) { + return false; + } + } +} diff --git a/lib/service/todo_service.dart b/lib/service/todo_service.dart index 58b59f4..7f09476 100644 --- a/lib/service/todo_service.dart +++ b/lib/service/todo_service.dart @@ -28,11 +28,6 @@ class TodoService { } } - Future updateTodoCompletion(Todo todo, bool isCompleted) async { - todo.isCompleted = isCompleted; - return await updateTodo(todo); - } - Future deleteTodo(Todo todo) async { try { await todo.delete(); diff --git a/lib/utils/flisp_utils.dart b/lib/utils/flisp_utils.dart new file mode 100644 index 0000000..67bd6ab --- /dev/null +++ b/lib/utils/flisp_utils.dart @@ -0,0 +1,14 @@ +import 'package:flisp_app/models/flisp.dart'; + +List getActiveFlisps(FlispTab currentTab, List flisps) { + switch (currentTab) { + case FlispTab.life: + return flisps.where((flisp) => flisp.tag == FlispTab.life).toList(); + case FlispTab.work: + return flisps.where((flisp) => flisp.tag == FlispTab.work).toList(); + case FlispTab.study: + return flisps.where((flisp) => flisp.tag == FlispTab.study).toList(); + default: + return flisps; + } +} diff --git a/lib/widgets/flisp_form.dart b/lib/widgets/flisp_form.dart new file mode 100644 index 0000000..74f9cfd --- /dev/null +++ b/lib/widgets/flisp_form.dart @@ -0,0 +1,173 @@ +import 'package:flisp_app/models/flisp.dart'; +import 'package:flisp_app/provider/flisp_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:provider/provider.dart'; + +class FlispForm extends StatefulWidget { + final GlobalKey formKey; + final bool isEditing; + final Flisp? initialFlisp; + + const FlispForm({ + super.key, + required this.formKey, + required this.isEditing, + this.initialFlisp, + }); + + @override + State createState() => _FlispFormState(); +} + +class _FlispFormState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + final int maxContentCount = 30; + final provider = Provider.of(context); + + Widget buildTitle() { + return Row( + children: [ + Icon( + widget.isEditing ? Icons.edit_note : Icons.add_task, + color: Colors.orange, + size: 24, + ), + SizedBox(width: 8), + Text( + widget.isEditing ? '编辑闪灵' : '添加闪灵', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.orange, + ), + ), + ], + ); + } + + FormBuilderTextField buildContentField() { + return FormBuilderTextField( + name: 'content', + initialValue: provider.formItem.content, + onChanged: (value) { + setState(() { + provider.formItem.content = value ?? ''; + }); + }, + decoration: InputDecoration( + labelText: '内容', + hintText: '请输入闪灵内容...', + counterText: '', + suffixText: '${provider.formItem.content.length}/$maxContentCount', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: BorderSide(color: Colors.grey.shade200), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: BorderSide(color: Colors.grey.shade200), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: BorderSide(color: Colors.orange), + ), + filled: true, + fillColor: Colors.white, + prefixIcon: Icon(Icons.description, color: Colors.green), + contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14), + ), + maxLines: 3, + maxLength: maxContentCount, + validator: (value) { + if (value != null && value.length > maxContentCount) { + return '内容不能超过$maxContentCount个字符'; + } + return null; + }, + ); + } + + FormBuilderRadioGroup builderRadioGroup() { + return FormBuilderRadioGroup( + name: 'tag', + initialValue: provider.formItem.tag, + decoration: InputDecoration( + border: InputBorder.none, + contentPadding: EdgeInsets.zero, + ), + orientation: OptionsOrientation.horizontal, + wrapSpacing: 6, + options: + FlispTag.values.map((priority) { + return FormBuilderFieldOption( + value: priority, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [Text(priority.label)], + ), + ); + }).toList(), + onChanged: (value) { + if (value != null) { + setState(() { + provider.formItem.tag = value; + }); + } + }, + ); + } + + Container buildTagField() { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey.shade300, width: 1), + ), + padding: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.category, color: Colors.orange), + SizedBox(width: 6), + Text('分类'), + ], + ), + builderRadioGroup(), + ], + ), + ); + } + + FormBuilder buildForm() { + return FormBuilder( + key: widget.formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + buildContentField(), + SizedBox(height: 12), + buildTagField(), + ], + ), + ); + } + + return Padding( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [buildTitle(), SizedBox(height: 20), buildForm()], + ), + ); + } +} diff --git a/lib/widgets/flisp_widget.dart b/lib/widgets/flisp_widget.dart new file mode 100644 index 0000000..8a2593b --- /dev/null +++ b/lib/widgets/flisp_widget.dart @@ -0,0 +1,205 @@ +import 'package:flisp_app/models/flisp.dart'; +import 'package:flisp_app/widgets/common.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:toggle_switch/toggle_switch.dart'; + +Widget buildTabs({ + required FlispTab currentTab, + required ValueChanged onTabChanged, +}) { + return Container( + padding: EdgeInsets.all(8), + child: ToggleSwitch( + minWidth: 90.0, + minHeight: 40.0, + initialLabelIndex: FlispTab.values.indexOf(currentTab), + totalSwitches: FlispTab.values.length, + labels: FlispTab.values.map((e) => e.label).toList(), + activeBgColor: [Colors.orange.shade600], + 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]); + } + }, + ), + ); +} + +Widget buildFlispList({ + required List flisps, + required ValueChanged onEdit, +}) { + return ListView.separated( + itemCount: flisps.length, + separatorBuilder: (context, index) => SizedBox(height: 8), + itemBuilder: (context, index) { + final flisp = flisps[index]; + return _buildFlispItem(flisp: flisp, onEdit: onEdit); + }, + ); +} + +Widget _buildFlispContent(Flisp flisp) { + return RichText( + text: TextSpan( + text: flisp.content, + style: const TextStyle( + color: Colors.black87, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + ); +} + +Widget _buildFlispImage(Flisp flisp) { + return Container( + height: 150, + margin: const EdgeInsets.only(bottom: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + image: NetworkImage(flisp.imageUrl), + fit: BoxFit.cover, + ), + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.black.withOpacity(0.3), + ), + alignment: Alignment.topRight, + child: const Padding( + padding: EdgeInsets.all(6.0), + child: Icon(Icons.image, color: Colors.white, size: 20), + ), + ), + ); +} + +Widget _buildFlispVideo(Flisp flisp) { + return Container( + height: 120, + margin: const EdgeInsets.only(bottom: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.grey[300], + ), + child: Stack( + alignment: Alignment.center, + children: [ + // 视频缩略图背景 + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.blue[100], + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Colors.blue[200]!, Colors.blue[400]!], + ), + ), + ), + // 播放按钮 + const CircleAvatar( + backgroundColor: Colors.white, + radius: 24, + child: Icon(Icons.play_arrow, color: Colors.red, size: 36), + ), + // 视频标识 + const Positioned( + top: 8, + right: 8, + child: Icon(Icons.videocam, color: Colors.red, size: 20), + ), + // 视频时长 + const Positioned( + bottom: 8, + right: 8, + child: Text( + '02:30', + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ); +} + +Widget _buildFlispTag(Flisp flisp) { + return Row( + children: [ + // 只有一个标签,直接显示 + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + flisp.tag.label, + style: const TextStyle(fontSize: 12, color: Colors.white), + ), + ), + const Spacer(), + // 时间在后 + Text( + DateFormat('yyyy-MM-dd HH:mm').format(flisp.createTime), + style: TextStyle(fontSize: 12, color: Colors.grey[500]), + ), + ], + ); +} + +Widget _buildFlispItem({ + required Flisp flisp, + required ValueChanged onEdit, +}) { + final hasImage = flisp.imageUrl.isNotEmpty; + final hasVideo = flisp.videoUrl.isNotEmpty; + + return buildCard( + child: InkWell( + onTap: () => onEdit(flisp), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildFlispContent(flisp), + const SizedBox(height: 8), + if (hasImage) _buildFlispImage(flisp), + const SizedBox(height: 4), + if (hasVideo) _buildFlispVideo(flisp), + const SizedBox(height: 4), + _buildFlispTag(flisp), + ], + ), + ), + ); +} + +// 空状态 +Widget buildEmptyState() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.checklist, size: 80, color: Colors.orange.shade600), + Text( + '📝 还没有闪灵\n点击➕号添加第一个任务吧~', + textAlign: TextAlign.center, + style: TextStyle(color: Colors.orange.shade600), + ), + ], + ), + ); +} diff --git a/lib/widgets/todo_form.dart b/lib/widgets/todo_form.dart index e2bb304..1dcdabe 100644 --- a/lib/widgets/todo_form.dart +++ b/lib/widgets/todo_form.dart @@ -64,7 +64,25 @@ class _TodoFormState extends State { }); }, decoration: InputDecoration( - labelText: '标题', + label: RichText( + text: TextSpan( + text: '标题', + style: TextStyle( + color: Colors.grey.shade700, + fontSize: 16, + ), + children: const [ + TextSpan( + text: '*', + style: TextStyle( + color: Colors.red, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), hintText: '请输入待办事项标题...', counterText: '', suffixText: '${provider.formItem.title.length}/$maxTitleCount', @@ -174,7 +192,7 @@ class _TodoFormState extends State { ? Colors.grey : Colors.black87, ), - prefixIcon: Icon(Icons.calendar_today, color: Colors.purple), + prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade200), @@ -239,7 +257,7 @@ class _TodoFormState extends State { ? Colors.grey : Colors.black87, ), - prefixIcon: Icon(Icons.calendar_today, color: Colors.purple), + prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade200),