mini_day_item.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import 'package:calendar_view/utils/calendar_util.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. /// 小日历的每一格日期
  5. class MiniDayItem extends StatefulWidget {
  6. const MiniDayItem({super.key, required this.dayData, required this.onSelect});
  7. final DayStructure dayData;
  8. final ValueChanged<int> onSelect;
  9. @override
  10. State<MiniDayItem> createState() => _MyWidgetState();
  11. }
  12. class _MyWidgetState extends State<MiniDayItem> {
  13. late DayStructure _dayData;
  14. late BoxDecoration containerDecoration;
  15. late TextStyle dayTextStyle;
  16. /// TODO[Gavin]: i18n
  17. get displayStr => _dayData.isToday ? '今' : _dayData.date.day.toString();
  18. @override
  19. void initState() {
  20. super.initState();
  21. _dayData = widget.dayData;
  22. _initStyle();
  23. }
  24. @override
  25. void didUpdateWidget(MiniDayItem oldWidget) {
  26. super.didUpdateWidget(oldWidget);
  27. _dayData = widget.dayData;
  28. _initStyle();
  29. }
  30. /// 初始化样式
  31. /// 存在三种背景样式,选中,未选中,“今日”未选中
  32. /// 存在四种文字样式,选中,未选中,非当月,“今日”未选中
  33. void _initStyle() {
  34. if (_dayData.isSelected) {
  35. dayTextStyle = TextStyle(
  36. height: _dayData.isToday ? null : 1,
  37. fontSize: 12,
  38. color: Colors.white,
  39. );
  40. containerDecoration = BoxDecoration(
  41. color: Colors.blue,
  42. borderRadius: BorderRadius.circular(15),
  43. );
  44. } else {
  45. if (_dayData.isToday) {
  46. dayTextStyle = const TextStyle(
  47. height: null,
  48. fontSize: 12,
  49. color: Colors.blue,
  50. );
  51. containerDecoration = BoxDecoration(
  52. color: const Color.fromARGB(255, 224, 241, 255),
  53. borderRadius: BorderRadius.circular(15),
  54. );
  55. } else {
  56. dayTextStyle = TextStyle(
  57. height: _dayData.isToday ? null : 1,
  58. fontSize: 12,
  59. color: _dayData.isCurrentMonth ? Colors.black87 : Colors.black26,
  60. );
  61. containerDecoration = const BoxDecoration(
  62. color: Colors.transparent,
  63. );
  64. }
  65. }
  66. }
  67. @override
  68. Widget build(BuildContext context) {
  69. return GestureDetector(
  70. onTap: () {
  71. widget.onSelect.call(_dayData.index);
  72. },
  73. child: MouseRegion(
  74. cursor: SystemMouseCursors.click,
  75. onEnter: _handleMouthEnter,
  76. onExit: _handleMouthExit,
  77. child: Column(
  78. children: [
  79. Container(
  80. decoration: containerDecoration,
  81. height: 25,
  82. width: 25,
  83. child: Center(
  84. child: Text(displayStr, style: dayTextStyle),
  85. ),
  86. ),
  87. const SizedBox(
  88. height: 2,
  89. ),
  90. _buildScheduleIndicator()
  91. ],
  92. ),
  93. ),
  94. );
  95. }
  96. /// 构建日程指示器
  97. Widget _buildScheduleIndicator() {
  98. return Container(
  99. height: 4,
  100. width: 4,
  101. decoration: _dayData.hasSchedule
  102. ? BoxDecoration(
  103. color: const Color.fromARGB(255, 218, 219, 220),
  104. borderRadius: BorderRadius.circular(2),
  105. )
  106. : null,
  107. );
  108. }
  109. /// 鼠标移入时,如果未选中,背景色设置为灰色
  110. void _handleMouthEnter(PointerEnterEvent event) {
  111. if (!_dayData.isSelected) {
  112. setState(() {
  113. containerDecoration = BoxDecoration(
  114. color: const Color.fromARGB(255, 234, 236, 237),
  115. borderRadius: BorderRadius.circular(15),
  116. );
  117. });
  118. }
  119. }
  120. /// 鼠标移出时,如果未选中,背景色设置为透明
  121. void _handleMouthExit(PointerExitEvent event) {
  122. if (!_dayData.isSelected) {
  123. _initStyle();
  124. setState(() {});
  125. }
  126. }
  127. }