Browse Source

完成主视图

gavin.chen 2 years ago
parent
commit
b31d401c89

+ 5 - 34
lib/calendar_view/month_calendar/month_calendar_item.dart

@@ -1,4 +1,5 @@
 import 'package:calendar_view/calendar_view/calendar_util.dart';
+import 'package:calendar_view/calendar_view/month_calendar/schedule_list.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 
@@ -40,7 +41,7 @@ class _MyWidgetState extends State<MonthDayItem> {
     if (_dayData.isSelected) {
       dayTextStyle = TextStyle(
         height: _dayData.isToday ? null : 1,
-        fontSize: 12,
+        fontSize: 14,
         color: Colors.white,
       );
       containerDecoration = BoxDecoration(
@@ -51,7 +52,7 @@ class _MyWidgetState extends State<MonthDayItem> {
       if (_dayData.isToday) {
         dayTextStyle = const TextStyle(
           height: null,
-          fontSize: 12,
+          fontSize: 14,
           color: Colors.blue,
         );
         containerDecoration = BoxDecoration(
@@ -61,7 +62,7 @@ class _MyWidgetState extends State<MonthDayItem> {
       } else {
         dayTextStyle = TextStyle(
           height: _dayData.isToday ? null : 1,
-          fontSize: 12,
+          fontSize: 14,
           color: _dayData.isCurrentMonth ? Colors.black87 : Colors.black26,
         );
         containerDecoration = const BoxDecoration(
@@ -75,8 +76,6 @@ class _MyWidgetState extends State<MonthDayItem> {
   Widget build(BuildContext context) {
     return MouseRegion(
       cursor: SystemMouseCursors.click,
-      onEnter: _handleMouthEnter,
-      onExit: _handleMouthExit,
       child: GestureDetector(
         onTap: () {
           widget.onSelect.call(_dayData.index);
@@ -107,36 +106,8 @@ class _MyWidgetState extends State<MonthDayItem> {
     return Expanded(
       child: Container(
         width: double.infinity,
-        color: const Color.fromARGB(186, 252, 198, 194),
-        child: const Text(
-          'TODO List',
-          style: TextStyle(
-            fontSize: 18,
-            color: Colors.red,
-          ),
-          textAlign: TextAlign.center,
-        ),
+        child: const ScheduleList(),
       ),
     );
   }
-
-  /// 鼠标移入时,如果未选中,背景色设置为灰色
-  void _handleMouthEnter(PointerEnterEvent event) {
-    if (!_dayData.isSelected) {
-      setState(() {
-        containerDecoration = BoxDecoration(
-          color: const Color.fromARGB(255, 234, 236, 237),
-          borderRadius: BorderRadius.circular(15),
-        );
-      });
-    }
-  }
-
-  /// 鼠标移出时,如果未选中,背景色设置为透明
-  void _handleMouthExit(PointerExitEvent event) {
-    if (!_dayData.isSelected) {
-      _initStyle();
-      setState(() {});
-    }
-  }
 }

+ 109 - 0
lib/calendar_view/month_calendar/schedule_list.dart

@@ -0,0 +1,109 @@
+import 'dart:html';
+import 'package:calendar_view/calendar_view/calendar_util.dart';
+import 'package:flutter/material.dart';
+import 'package:calendar_view/utils/throttle.dart' as utils;
+
+class ScheduleList extends StatefulWidget {
+  const ScheduleList({Key? key}) : super(key: key);
+
+  @override
+  ScheduleListState createState() => ScheduleListState();
+}
+
+class ScheduleListState extends State<ScheduleList> {
+  static final List<ScheduleType> _mockScheduleTypeList = [
+    ScheduleType(typeName: '工作', isSelected: true, color: Colors.blue),
+    ScheduleType(typeName: '加班', isSelected: false, color: Colors.red),
+    ScheduleType(typeName: '学习', isSelected: false, color: Colors.green),
+    ScheduleType(typeName: '生活', isSelected: false, color: Colors.orange),
+    ScheduleType(typeName: '核酸', isSelected: false, color: Colors.purple),
+  ];
+  static List<ScheduleType> _scheduleTypeList = [];
+
+  /// 容器高度【动态】
+  double conatinerHeight = 0;
+
+  /// 每个item的高度
+  static const double _itemHeight = 20;
+
+  /// 容纳的数量
+  int itemCount = 0;
+
+  @override
+  void initState() {
+    super.initState();
+    _scheduleTypeList = _mockScheduleTypeList;
+    window.onResize.listen(((event) => {
+          utils.throttle(() {
+            _onWindowResize();
+          }, 'onResize_${widget.hashCode}', 500)
+        }));
+    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
+      _onWindowResize();
+    });
+  }
+
+  void _onWindowResize() {
+    setState(() {
+      conatinerHeight = context.size!.height;
+      itemCount = _countItemNum();
+    });
+    _scheduleTypeList = _mockScheduleTypeList;
+    // 如果缩减了数量,则将最后一项显示的内容设置为更多
+    if (itemCount < _scheduleTypeList.length) {
+      _scheduleTypeList[itemCount - 1] = ScheduleType(
+          typeName: '还有${_scheduleTypeList.length - itemCount + 1}项...',
+          isSelected: false,
+          color: Colors.grey);
+    }
+  }
+
+  /// 计算可容纳的item数量
+  int _countItemNum() {
+    final maxNum = (conatinerHeight / _itemHeight).floor();
+    return maxNum > _scheduleTypeList.length
+        ? _scheduleTypeList.length
+        : maxNum;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      child: _buildScheduleTypeList(),
+    );
+  }
+
+  Widget _buildScheduleTypeList() {
+    return ListView.builder(
+      itemCount: itemCount,
+      itemBuilder: (context, index) {
+        return _buildScheduleTypeItem(_scheduleTypeList[index]);
+      },
+    );
+  }
+
+  Widget _buildScheduleTypeItem(ScheduleType scheduleType) {
+    return Container(
+      height: _itemHeight,
+      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0),
+      color: Colors.transparent,
+      child: Row(
+        children: [
+          Container(
+            width: 6,
+            height: 6,
+            decoration: BoxDecoration(
+              color: scheduleType.color,
+              borderRadius: BorderRadius.circular(5),
+            ),
+          ),
+          const SizedBox(width: 10),
+          Text(
+            scheduleType.typeName,
+            style: const TextStyle(fontSize: 12),
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 56 - 0
lib/utils/throttle.dart

@@ -0,0 +1,56 @@
+import 'dart:async';
+
+// 节流函数列表
+Map<String, Timer> _funcThrottle = {};
+// 节流函数上次触发的时间
+Map<String, DateTime> _funcThrottleLastCall = {};
+Function? _lastFunc;
+
+/// 函数节流
+///
+/// [func]: 要执行的方法
+/// [funcTag]: 方法标识符
+/// [milliseconds]: 要迟延的毫秒时间
+Function throttle(Function func, String funcTag, [int milliseconds = 2000]) {
+  target() {
+    // print('对 $funcTag 进行函数节流');
+    String key = funcTag.toString();
+    Timer? _timer = _funcThrottle[key];
+    if (_timer == null) {
+      // 判断是否是第一次调用
+      if (_funcThrottleLastCall[key] == null) {
+        func.call();
+        _funcThrottleLastCall[key] = DateTime.now();
+      } else {
+        // 判断是否超过了延迟时间
+        if (DateTime.now()
+                .difference(_funcThrottleLastCall[key]!)
+                .inMilliseconds >
+            milliseconds) {
+          _funcThrottleLastCall[key] = DateTime.now();
+          func.call();
+        } else {
+          _lastFunc = func;
+        }
+      }
+      _timer = Timer(Duration(milliseconds: milliseconds), () {
+        final lastFunc = _lastFunc;
+        if (lastFunc != null) {
+          _lastFunc!.call();
+          _funcThrottleLastCall[key] = DateTime.now();
+          _lastFunc = null;
+        }
+        Timer? t = _funcThrottle.remove(key);
+        t?.cancel();
+        t = null;
+      });
+      _funcThrottle[key] = _timer;
+    } else {
+      _lastFunc = func;
+    }
+  }
+
+  target();
+
+  return target;
+}