calendar_main_panel.dart 6.5 KB

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