mini_calendar.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import 'package:calendar_view/calendar_controller/controller.dart';
  2. import 'package:calendar_view/utils/calendar_util.dart';
  3. import 'package:calendar_view/calendar_view/mini_calendar/mini_day_item.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:get/get.dart';
  6. class MiniCalendar extends StatefulWidget {
  7. const MiniCalendar({super.key});
  8. @override
  9. State<MiniCalendar> createState() => _MiniCalendarState();
  10. }
  11. class _MiniCalendarState extends State<MiniCalendar> {
  12. String currYearMonth = ''; // 当前年月
  13. List<DayStructure> daysList = []; // 当前控制器的日期列表
  14. CalendarController calendarController = Get.find<CalendarController>();
  15. @override
  16. void initState() {
  17. super.initState();
  18. currYearMonth = calendarController.currentYearMonth;
  19. daysList = calendarController.daysList;
  20. calendarController.onDaysListChange.addListener(_onDaysListChange);
  21. }
  22. @override
  23. void dispose() {
  24. super.dispose();
  25. calendarController.onDaysListChange.removeListener(_onDaysListChange);
  26. }
  27. void _onDaysListChange(_, e) {
  28. setState(() {
  29. currYearMonth = calendarController.currentYearMonth;
  30. daysList = calendarController.daysList;
  31. });
  32. }
  33. @override
  34. Widget build(BuildContext context) {
  35. return Column(
  36. children: <Widget>[
  37. _buildMiniCalendarTop(),
  38. _buildMiniCalendarBody(),
  39. const SizedBox(
  40. height: 10,
  41. ),
  42. ],
  43. );
  44. }
  45. Widget _buildMiniCalendarTop() {
  46. /// 按钮样式
  47. final iconButtonStyle = ButtonStyle(
  48. padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
  49. const EdgeInsets.all(0)),
  50. backgroundColor: MaterialStateProperty.all<Color>(Colors.transparent),
  51. shadowColor: MaterialStateProperty.all<Color>(Colors.transparent),
  52. overlayColor: MaterialStateProperty.all<Color>(
  53. const Color.fromARGB(255, 224, 226, 228)),
  54. foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
  55. surfaceTintColor: MaterialStateProperty.all<Color>(Colors.white),
  56. );
  57. return SizedBox(
  58. height: 40,
  59. child: Row(
  60. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  61. children: <Widget>[
  62. const SizedBox(
  63. width: 10,
  64. ),
  65. Text(
  66. currYearMonth,
  67. style: const TextStyle(
  68. fontSize: 16,
  69. ),
  70. ),
  71. Expanded(child: Container()),
  72. SizedBox(
  73. width: 32,
  74. height: 32,
  75. child: ElevatedButton(
  76. style: iconButtonStyle,
  77. onPressed: calendarController.handleLastMonth,
  78. child: const Icon(
  79. Icons.keyboard_arrow_left,
  80. size: 20,
  81. color: Colors.black38,
  82. ),
  83. ),
  84. ),
  85. SizedBox(
  86. width: 32,
  87. height: 32,
  88. child: ElevatedButton(
  89. style: iconButtonStyle,
  90. onPressed: calendarController.handleNextMonth,
  91. child: const Icon(
  92. Icons.keyboard_arrow_right,
  93. size: 20,
  94. color: Colors.black38,
  95. ),
  96. ),
  97. ),
  98. ],
  99. ),
  100. );
  101. }
  102. Widget _buildMiniCalendarBody() {
  103. return Container(
  104. padding: EdgeInsets.symmetric(horizontal: 5),
  105. child: Column(
  106. children: <Widget>[
  107. _buildMiniCalendarWeekTitle(),
  108. const SizedBox(
  109. height: 5,
  110. ),
  111. _buildMiniCalendarDaysBody(),
  112. ],
  113. ),
  114. );
  115. }
  116. /// 构建「日、一、二、三、四、五、六」的标题
  117. Widget _buildMiniCalendarWeekTitle() {
  118. return Container(
  119. height: 30,
  120. child: Row(
  121. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  122. children: <Widget>[
  123. /// TODO[Gavin]: i18n
  124. _buildEachTitle('日'),
  125. _buildEachTitle('一'),
  126. _buildEachTitle('二'),
  127. _buildEachTitle('三'),
  128. _buildEachTitle('四'),
  129. _buildEachTitle('五'),
  130. _buildEachTitle('六'),
  131. ],
  132. ),
  133. );
  134. }
  135. Widget _buildEachTitle(String title) {
  136. const weekTextStyle = TextStyle(fontSize: 12, color: Colors.black54);
  137. return SizedBox(
  138. width: 25,
  139. child: Text(
  140. title,
  141. style: weekTextStyle,
  142. textAlign: TextAlign.center,
  143. ),
  144. );
  145. }
  146. /// 构建日历主体
  147. Widget _buildMiniCalendarDaysBody() {
  148. // 将35天分成5个周
  149. final weeksInMonth = <List<DayStructure>>[];
  150. for (var i = 0; i < daysList.length; i += 7) {
  151. weeksInMonth.add(daysList.sublist(i, i + 7));
  152. }
  153. return SizedBox(
  154. child: Column(
  155. children: weeksInMonth.map(_buildMiniCalendarDayRow).toList(),
  156. ),
  157. );
  158. }
  159. /// 构建每一行(周)
  160. Widget _buildMiniCalendarDayRow(List<DayStructure> sevenDays) {
  161. return Container(
  162. height: 32,
  163. child: Row(
  164. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  165. children: sevenDays.map(_buildEachDay).toList(),
  166. ),
  167. );
  168. }
  169. /// 构建每一天
  170. Widget _buildEachDay(DayStructure day) {
  171. return MiniDayItem(
  172. dayData: day,
  173. onSelect: (v) => calendarController.handleSelectedDayByIndex(v),
  174. );
  175. }
  176. }