Flutter日历管理插件flutter_clean_calendar的使用

Flutter日历管理插件flutter_clean_calendar的使用

简介

flutter_clean_calendar 是一个基于 flutter_calendar 的简单 Flutter 日历组件。感谢 @AppleEducate 对该项目的贡献。你可以通过上下滑动来切换周视图或月视图。它会显示特定日期的事件数量,并用不同的颜色显示已完成的事件。

使用方法

Calendar 组件嵌入到 Column 中。在日历下方(作为 Column 中的第二个子组件)放置一个 ListView.builder 来渲染当天的事件列表。

Column(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[
    Container(
      child: Calendar(
        startOnMonday: true,
        weekDays: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
        events: _events,
        onRangeSelected: (range) => print('Range is ${range.from}, ${range.to}'),
        onDateSelected: (date) => _handleNewDate(date),
        isExpandable: true,
        eventDoneColor: Colors.green,
        selectedColor: Colors.pink,
        todayColor: Colors.blue,
        eventColor: Colors.grey,
        locale: 'de_DE',
        todayButtonText: 'Heute',
        expandableDateFormat: 'EEEE, dd. MMMM yyyy',
        dayOfWeekStyle: TextStyle(
            color: Colors.black,
            fontWeight: FontWeight.w800,
            fontSize: 11),
      ),
    ),
    _buildEventList()
  ],
),

...

/// 这个函数 [_buildEventList] 构建了所选日期的事件列表。这个列表会在周视图或月视图下方被渲染。
Widget _buildEventList() {
  return Expanded(
    child: ListView.builder(
      padding: EdgeInsets.all(0.0),
      itemBuilder: (BuildContext context, int index) {
        final CleanCalendarEvent event = _selectedEvents[index];
        final String start = DateFormat('HH:mm').format(event.startTime).toString();
        final String end = DateFormat('HH:mm').format(event.endTime).toString();
        return ListTile(
          contentPadding: EdgeInsets.only(left: 2.0, right: 8.0, top: 2.0, bottom: 2.0),
          leading: Container(
            width: 10.0,
            color: event.color,
          ),
          title: Text(event.summary),
          subtitle: event.description.isNotEmpty ? Text(event.description) : null,
          trailing: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [Text(start), Text(end)],
          ),
          onTap: () {},
        );
      },
      itemCount: _selectedEvents.length,
    ),
  );
}

属性

以下是 Calendar 组件的一些常用属性:

/// [onDateSelected] 是一个类型为 [ValueChanged<DateTime>] 的回调函数,当点击某一天时会被触发
/// [onMonthChanged] 是一个类型为 [ValueChanged<DateTime>] 的回调函数,当切换到另一个月份时会被触发
/// [onExpandStateChanged] 是一个类型为 [ValueChanged<bool>] 的回调函数,当视图从展开状态切换到收缩状态时会被触发
/// [onRangeSelected] 是一个类型为 [ValueChanged] 的回调函数,当选择的范围改变时(切换到下一个或上一个周/月时)会被触发
/// [isExpandable] 是一个 [bool] 类型的参数,用于控制是否可以从周视图切换到月视图。默认值为 [false]
/// [dayBuilder] 可以包含一个 [Widget]。如果这个属性不为空,则这个 widget 将用于渲染日历的格子(可以自定义视图)
/// [hideArrows] 是一个 [bool] 类型的参数。设置为 [true] 时,顶部导航到下一周/月的箭头会被隐藏。默认值为 [false]
/// [hideTodayIcon] 是一个 [bool] 类型的参数。设置为 [true] 时,顶部导航到今天的按钮会被隐藏。默认值为 [false]
/// [hideBottomBar] 目前没有功能。默认值为 [false]
/// [events] 是一个类型为 [Map<DateTime, List<CleanCalendarEvent>>] 的数据结构,用于存储要显示的事件
/// [selectedColor] 是选择日期的圆圈的颜色
/// [todayColor] 是今天日期的颜色
/// [todayButtonText] 是一个 [String] 类型的参数。可以通过这个属性设置导航到今天的按钮的文本。如果不设置,默认为 "Today"
/// [eventColor] 允许你可选地指定事件(点)的颜色。如果没有设置 [CleanCaendarEvents] 的颜色属性,那么日历将使用这个参数
/// [eventDoneColor] 可以通过这个属性定义“已完成”事件的颜色,即过去的事件
/// [initialDate] 是一个类型为 [DateTime] 的参数。它可以包含一个可选的开始日期。这是日历初始选择的日期。默认情况下不设置此参数。然后日历使用 [DateTime.now()]
/// [isExpanded] 是一个 [bool] 类型的参数。如果设置为 [true],日历将以月视图形式呈现
/// [weekDays] 包含一个 [List<String>] 定义了一周的天数名称,以便根据当前的语言环境命名它们
/// [locale] 是一个 [String] 类型的参数。这个设置用于根据当前的语言环境格式化日期
/// [startOnMonday] 是一个 [bool] 类型的参数。这个参数允许日历确定一周的第一天
/// [dayOfWeekStyle] 是一个 [TextStyle] 用于设置顶部条中星期几名称的文本样式
/// [bottomBarTextStyle] 是一个 [TextStyle],用于设置底部条中的文本样式
/// [bottomBarArrowColor] 可以设置底部条中展开/压缩日历的箭头颜色
/// [bottomBarColor] 设置底部条的颜色
/// [expandableDateFormat] 定义了底部条中日期的格式
final ValueChanged<DateTime> onDateSelected;
final ValueChanged<DateTime> onMonthChanged;
final ValueChanged<bool> onExpandStateChanged;
final ValueChanged onRangeSelected;
final bool isExpandable;
final DayBuilder dayBuilder;
final bool hideArrows;
final bool hideTodayIcon;
final Map<DateTime, List<CleanCalendarEvent>> events;
final Color selectedColor;
final Color todayColor;
final String todayButtonText;
final Color eventColor;
final Color eventDoneColor;
final DateTime initialDate;
final bool isExpanded;
final List<String> weekDays;
final String locale;
final bool startOnMonday;
final bool hideBottomBar;
final TextStyle dayOfWeekStyle;
final TextStyle bottomBarTextStyle;
final Color bottomBarArrowColor;
final Color bottomBarColor;
final String expandableDateFormat;

示例事件数据

由于引入了 CleanCalendarEvent 类,事件映射的语法发生了变化。

final Map<DateTime, List<CleanCalendarEvent>> _events = {
  DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day): [
    CleanCalendarEvent('Event A',
        startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 10, 0),
        endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 12, 0),
        description: 'A special event',
        color: Colors.blue[700]),
  ],
  DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2): [
    CleanCalendarEvent('Event B',
        startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 10, 0),
        endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 12, 0),
        color: Colors.orange),
    CleanCalendarEvent('Event C',
        startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
        endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
        color: Colors.pink),
  ],
};

示例代码

以下是一个完整的示例代码,展示了如何使用 flutter_clean_calendar 插件:

import 'package:flutter/material.dart';
import 'package:flutter_clean_calendar/flutter_clean_calendar.dart';
import 'package:flutter_clean_calendar/clean_calendar_event.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // 这个小部件是应用的根节点
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Clean Calendar Demo',
      home: CalendarScreen(),
    );
  }
}

class CalendarScreen extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() {
    return _CalendarScreenState();
  }
}

class _CalendarScreenState extends State<CalendarScreen> {
  final Map<DateTime, List<CleanCalendarEvent>> _events = {
    DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day): [
      CleanCalendarEvent('Event A',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 10, 0),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 12, 0),
          description: 'A special event',
          color: Colors.blue[700]),
    ],
    DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2): [
      CleanCalendarEvent('Event B',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 10, 0),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 12, 0),
          color: Colors.orange),
      CleanCalendarEvent('Event C',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
          color: Colors.pink),
    ],
    DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 3): [
      CleanCalendarEvent('Event B',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 10, 0),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 12, 0),
          color: Colors.orange),
      CleanCalendarEvent('Event C',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
          color: Colors.pink),
      CleanCalendarEvent('Event D',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
          color: Colors.amber),
      CleanCalendarEvent('Event E',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
          color: Colors.deepOrange),
      CleanCalendarEvent('Event F',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
          color: Colors.green),
      CleanCalendarEvent('Event G',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
          color: Colors.indigo),
      CleanCalendarEvent('Event H',
          startTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 14, 30),
          endTime: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 2, 17, 0),
          color: Colors.brown),
    ],
  };

  [@override](/user/override)
  void initState() {
    super.initState();
    // 在首次加载时强制选择今天,以便显示当天的事件列表。
    _handleNewDate(DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day));
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Calendar(
          startOnMonday: true,
          weekDays: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
          events: _events,
          isExpandable: true,
          eventDoneColor: Colors.green,
          selectedColor: Colors.pink,
          todayColor: Colors.blue,
          eventColor: Colors.grey,
          locale: 'de_DE',
          todayButtonText: 'Heute',
          isExpanded: true,
          expandableDateFormat: 'EEEE, dd. MMMM yyyy',
          dayOfWeekStyle: TextStyle(
              color: Colors.black, fontWeight: FontWeight.w800, fontSize: 11),
        ),
      ),
    );
  }

  void _handleNewDate(date) {
    print('Date selected: $date');
  }
}

更多关于Flutter日历管理插件flutter_clean_calendar的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter日历管理插件flutter_clean_calendar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_clean_calendar 是一个用于在Flutter应用程序中显示和管理日历事件的插件。它提供了一个简洁、可定制的日历视图,支持选择日期、添加事件等功能。以下是使用 flutter_clean_calendar 的基本步骤和示例代码。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 flutter_clean_calendar 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_clean_calendar: ^3.1.0

然后运行 flutter pub get 以安装依赖。

2. 导入包

在需要使用日历的 Dart 文件中导入 flutter_clean_calendar 包:

import 'package:flutter_clean_calendar/flutter_clean_calendar.dart';

3. 使用 CleanCalendar

flutter_clean_calendar 提供了一个 CleanCalendar 小部件,你可以将其添加到你的应用程序中。以下是一个简单的示例:

import 'package:flutter/material.dart';
import 'package:flutter_clean_calendar/flutter_clean_calendar.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CalendarScreen(),
    );
  }
}

class CalendarScreen extends StatefulWidget {
  [@override](/user/override)
  _CalendarScreenState createState() => _CalendarScreenState();
}

class _CalendarScreenState extends State<CalendarScreen> {
  Map<DateTime, List<String>> events = {};

  [@override](/user/override)
  void initState() {
    super.initState();
    // 初始化一些事件
    events = {
      DateTime(2023, 10, 1): ['事件1', '事件2'],
      DateTime(2023, 10, 15): ['事件3'],
      DateTime(2023, 10, 20): ['事件4', '事件5'],
    };
  }

  void _handleDateSelect(DateTime date) {
    print('Selected date: $date');
    // 你可以在这里处理日期选择逻辑
    setState(() {
      if (events[date] == null) {
        events[date] = ['新事件'];
      } else {
        events[date]!.add('新事件');
      }
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Clean Calendar'),
      ),
      body: SafeArea(
        child: Calendar(
          startOnMonday: true,
          weekDays: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
          events: events,
          onDateSelected: _handleDateSelect,
          isExpandable: true,
          eventDoneColor: Colors.green,
          selectedColor: Colors.pink,
          todayColor: Colors.blue,
          eventColor: Colors.grey,
          bottomBarColor: Colors.white,
          bottomBarTextStyle: TextStyle(color: Colors.black),
          dayOfWeekStyle: TextStyle(color: Colors.black),
          locale: 'en_US',
          hideBottomBar: false,
          hideArrows: false,
          isExpanded: true,
          expandableDateFormat: 'EEEE, MMMM dd, yyyy',
        ),
      ),
    );
  }
}
回到顶部