calendar_main_panel.dart 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import 'package:calendar_view/calendar_controller/controller.dart';
  2. import 'package:calendar_view/calendar_page/calendar_views/calendar_month_view.dart';
  3. import 'package:calendar_view/calendar_page/my_calendar/my_calendar.dart';
  4. import 'package:calendar_view/popup_layer/popup_layer.dart';
  5. import 'package:calendar_view/popup_layer/popup_layer_controller.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:get/get.dart';
  8. /// 日历视图主体面板
  9. class CalendarMainPanel extends StatefulWidget {
  10. const CalendarMainPanel({super.key});
  11. @override
  12. State<CalendarMainPanel> createState() => _CalendarMainPanelState();
  13. }
  14. enum CalendarViewType { month, week, day, list }
  15. class _CalendarMainPanelState extends State<CalendarMainPanel> {
  16. /// TODO:[Gavin] 将 _viewType 也收入到 CalendarController 中
  17. final CalendarViewType _viewType = CalendarViewType.month;
  18. String _currYearMonthStr = ''; // 当前年月
  19. bool _isToday = true; // 是否是今天
  20. CalendarController calendarController = Get.find<CalendarController>();
  21. @override
  22. void initState() {
  23. super.initState();
  24. _isToday = calendarController.isToday;
  25. _currYearMonthStr = calendarController.currentYearMonth;
  26. calendarController.onDaysListChange.addListener(_onDaysListChange);
  27. }
  28. @override
  29. void dispose() {
  30. super.dispose();
  31. calendarController.onDaysListChange.removeListener(_onDaysListChange);
  32. }
  33. void _onDaysListChange(_, e) {
  34. setState(() {
  35. _isToday = calendarController.isToday;
  36. _currYearMonthStr = calendarController.currentYearMonth;
  37. });
  38. }
  39. /// 按钮样式
  40. final iconButtonStyle = ButtonStyle(
  41. padding:
  42. MaterialStateProperty.all<EdgeInsetsGeometry>(const EdgeInsets.all(0)),
  43. backgroundColor: MaterialStateProperty.all<Color>(Colors.transparent),
  44. shadowColor: MaterialStateProperty.all<Color>(Colors.transparent),
  45. overlayColor: MaterialStateProperty.all<Color>(
  46. const Color.fromARGB(255, 224, 226, 228)),
  47. foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
  48. surfaceTintColor: MaterialStateProperty.all<Color>(Colors.white),
  49. );
  50. @override
  51. Widget build(BuildContext context) {
  52. return Container(
  53. decoration: const BoxDecoration(
  54. border: Border(
  55. right: BorderSide(
  56. color: Colors.black12,
  57. width: 1,
  58. ),
  59. ),
  60. // color: const Color.fromARGB(90, 59, 255, 124),
  61. ),
  62. child: Column(
  63. children: <Widget>[
  64. _buildMainPanelTop(),
  65. Expanded(
  66. child: Stack(
  67. children: [
  68. _buildMainView(_viewType),
  69. const PopupLayer(),
  70. ],
  71. ),
  72. ),
  73. ],
  74. ),
  75. );
  76. }
  77. /// 构建顶部【今天、年月、视图切换器、更多】
  78. Widget _buildMainPanelTop() {
  79. return Container(
  80. height: 70,
  81. child: Container(
  82. padding: const EdgeInsets.symmetric(horizontal: 10),
  83. child: Row(
  84. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  85. children: <Widget>[
  86. _buildTodayButton(),
  87. _buildChangeMonthButtons(),
  88. _buildYearAndMonth(),
  89. Expanded(
  90. child: Container(),
  91. ),
  92. _buildMoreButton(),
  93. ],
  94. ),
  95. ),
  96. );
  97. }
  98. /// 【回到今天】按钮
  99. Widget _buildTodayButton() {
  100. return SizedBox(
  101. width: 50,
  102. height: 32,
  103. child: OutlinedButton(
  104. style: ButtonStyle(
  105. overlayColor: MaterialStateProperty.all<Color>(
  106. const Color.fromARGB(255, 235, 235, 235)),
  107. foregroundColor: MaterialStateProperty.all<Color>(
  108. _isToday ? Colors.black26 : Colors.black),
  109. backgroundColor: MaterialStateProperty.all<Color>(Colors.transparent),
  110. padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
  111. const EdgeInsets.all(0)),
  112. shadowColor: MaterialStateProperty.all<Color>(Colors.transparent),
  113. ),
  114. onPressed: _isToday ? null : calendarController.selectToday,
  115. // TODO[Gavin]: i18n
  116. child: const Text('今天'),
  117. ),
  118. );
  119. }
  120. /// 【上个月、下个月】按钮
  121. Widget _buildChangeMonthButtons() {
  122. return Container(
  123. margin: const EdgeInsets.symmetric(horizontal: 5),
  124. height: 40,
  125. child: Row(
  126. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  127. children: <Widget>[
  128. SizedBox(
  129. width: 32,
  130. height: 32,
  131. child: ElevatedButton(
  132. style: iconButtonStyle,
  133. onPressed: () => calendarController.handleLastMonth(true),
  134. child: const Icon(
  135. Icons.keyboard_arrow_left,
  136. size: 20,
  137. color: Colors.black,
  138. ),
  139. ),
  140. ),
  141. SizedBox(
  142. width: 32,
  143. height: 32,
  144. child: ElevatedButton(
  145. style: iconButtonStyle,
  146. onPressed: () => calendarController.handleNextMonth(true),
  147. child: const Icon(
  148. Icons.keyboard_arrow_right,
  149. size: 20,
  150. color: Colors.black,
  151. ),
  152. ),
  153. ),
  154. ],
  155. ),
  156. );
  157. }
  158. /// 年月
  159. Widget _buildYearAndMonth() {
  160. return Align(
  161. alignment: Alignment.center,
  162. child: Text(
  163. _currYearMonthStr,
  164. style: const TextStyle(
  165. height: 1.2,
  166. fontSize: 18,
  167. ),
  168. ),
  169. );
  170. }
  171. /// 【更多】按钮
  172. Widget _buildMoreButton() {
  173. return SizedBox(
  174. width: 50,
  175. height: 32,
  176. child: ElevatedButton(
  177. style: iconButtonStyle,
  178. onPressed: () {
  179. ScaffoldMessenger.of(context).showSnackBar(
  180. const SnackBar(
  181. duration: Duration(milliseconds: 500),
  182. content: Text('前方正在施工'),
  183. ),
  184. );
  185. },
  186. // TODO[Gavin]: i18n
  187. child: const Center(
  188. child: Icon(
  189. Icons.more_horiz,
  190. size: 20,
  191. color: Color.fromARGB(255, 116, 118, 119),
  192. ),
  193. ),
  194. ),
  195. );
  196. }
  197. /// 构建视图主体
  198. Widget _buildMainView(CalendarViewType type) {
  199. switch (type) {
  200. case CalendarViewType.month:
  201. return const CalendarMonthView();
  202. // TODO 周视图
  203. case CalendarViewType.week:
  204. return const MyCalendar();
  205. // TODO 日视图
  206. case CalendarViewType.day:
  207. return const MyCalendar();
  208. // TODO 列表视图
  209. case CalendarViewType.list:
  210. return const MyCalendar();
  211. default:
  212. return const CalendarMonthView();
  213. }
  214. }
  215. }