Flutter日历管理插件emor_calendar的使用
Flutter日历管理插件emor_calendar的使用
简介
此Flutter包提供了可自定义的日历,包含月视图和周视图,允许用户轻松导航和选择日期。该包还包括一个支持动态事件、日期范围限制和事件点颜色的事件日历小部件。
特性
- 月视图日历:显示一整个月份,并可选择日期。当前日期会被高亮显示,星期天用红色标记。
- 周视图日历:一次显示一周,并可通过滑动在不同周之间切换。
- 事件列表:显示所选日期的事件列表,每个事件项都有边框和内边距以提高清晰度。
安装
将此包添加到你的项目中,通过在pubspec.yaml
文件中包含以下内容:
dependencies:
flutter:
sdk: flutter
emor_calendar: ^0.0.2
然后运行:
flutter pub get
使用
月视图日历
import 'package:emor_calendar/emorphis_month_calendar.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('月视图日历')),
body: EmorphisMonthCalendar(),
),
);
}
}
周视图日历
import 'package:emor_calendar/emorphis_week_calendar.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('周视图日历')),
body: EmorphisWeekCalendar(),
),
);
}
}
事件列表
事件列表会自动显示在你选择有事件的日期时。你可以通过修改emorphis_calendar.dart
文件中的_buildEventList
方法来自定义事件列表。
import 'package:emor_calendar/emorphis_week_calendar.dart';
class EventCalendarScreen extends StatefulWidget {
@override
_EventCalendarScreenState createState() => _EventCalendarScreenState();
}
class _EventCalendarScreenState extends State<EventCalendarScreen> {
DateTime _focusedDay = DateTime.now();
DateTime _selectedDay = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day);
Map<DateTime, List<String>> _events = {};
@override
Widget build(BuildContext context) {
DateTime today = DateTime.now();
DateTime minDate = DateTime(today.year - 1, today.month, today.day);
DateTime maxDate = DateTime(today.year + 1, today.month, today.day);
return Scaffold(
appBar: AppBar(
title: const Text('Emorphis事件日历'),
backgroundColor: Colors.blue.withOpacity(0.5),
actions: [
_buildAddEventButton(),
],
),
body: Column(
children: [
EmorphisEventCalendar(
focusedDay: _focusedDay,
selectedDay: _selectedDay,
events: _events,
onDaySelected: (selectedDay) {
setState(() {
_selectedDay = selectedDay;
});
},
onFocusedDayChanged: (focusedDay) {
setState(() {
_focusedDay = focusedDay;
});
},
maxDate: maxDate,
minDate: minDate,
),
if (_events[_selectedDay] != null) _buildEventList(),
],
),
);
}
Future<String?> _addEventDialog() {
TextEditingController _controller = TextEditingController();
return showDialog<String>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text("添加事件"),
content: TextField(
controller: _controller,
decoration: const InputDecoration(hintText: '输入事件详情'),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('取消'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(_controller.text);
},
child: const Text('添加'),
),
],
);
},
);
}
Widget _buildEventList() {
return Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: ListView.builder(
shrinkWrap: true,
itemCount: _events[_selectedDay]?.length ?? 0,
itemBuilder: (context, index) {
return Container(
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.only(bottom: 8.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 0.5),
borderRadius: BorderRadius.circular(8.0),
),
child: Text(_events[_selectedDay]![index]),
);
},
),
),
);
}
Widget _buildAddEventButton() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () async {
String? event = await _addEventDialog();
if (event != null && event.isNotEmpty) {
final updatedEvents = Map<DateTime, List<String>>.from(_events);
updatedEvents[_selectedDay] = updatedEvents[_selectedDay] ?? [];
updatedEvents[_selectedDay]!.add(event);
setState(() {
_events = updatedEvents;
});
}
},
child: const Text("添加事件"),
),
);
}
}
节假日日历
import 'dart:convert';
import 'package:emor_calendar/calendar/emorphis_holiday_calendar.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'country.dart';
class HolidayCalendarScreen extends StatefulWidget {
@override
State<HolidayCalendarScreen> createState() => _HolidayCalendarScreenState();
}
class _HolidayCalendarScreenState extends State<HolidayCalendarScreen> {
List<Holiday> holidays = [];
DateTime _focusedDay = DateTime.now();
String _selectedCountryCode = 'US'; // 默认国家代码
final List<DropdownMenuItem<String>> dropdownItems =
countryList.map((Country country) {
return DropdownMenuItem<String>(
value: country.code,
child: Text(country.name),
);
}).toList();
Future<List<Holiday>> fetchHolidays(String countryCode, int year) async {
final response = await http.get(
Uri.parse('https://date.nager.at/Api/v2/PublicHolidays/$year/$countryCode'),
);
if (response.statusCode == 200) {
final List<dynamic> data = json.decode(response.body);
return data.map((holiday) {
return Holiday(
DateTime.parse(holiday['date']),
holiday['name'],
);
}).toList();
} else {
setState(() {
_focusedDay = _focusedDay;
holidays = [];
});
throw Exception('加载节假日失败');
}
}
void _updateHolidays(DateTime newFocusedDay) {
final newYear = newFocusedDay.year;
fetchHolidays(_selectedCountryCode, newYear).then(
(value) {
holidays = [];
setState(() {
holidays = value;
_focusedDay = newFocusedDay;
});
},
);
}
void _onCountryCodeChanged(String? newCountryCode) {
if (newCountryCode != null) {
setState(() {
_selectedCountryCode = newCountryCode;
_updateHolidays(_focusedDay);
});
}
}
@override
void initState() {
super.initState();
// 获取当前年份的节假日
_updateHolidays(DateTime.now());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('节假日日历'),
actions: [
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: 150, // 调整宽度
child: DropdownButton<String>(
value: _selectedCountryCode,
onChanged: _onCountryCodeChanged,
items: dropdownItems,
isExpanded: true, // 确保下拉菜单填充宽度
autofocus: true,
),
),
),
],
),
body: EmorphisHolidayCalendar(
holidays: holidays,
initialFocusedDay: _focusedDay,
initialSelectedDay: DateTime.now(),
onFocusedDayChanged: _updateHolidays,
),
);
}
}
国家模型
class Country {
final String code;
final String name;
Country(this.code, this.name);
}
final List<Country> countryList = [
Country('AF', '阿富汗'),
Country('AL', '阿尔巴尼亚'),
Country('DZ', '阿尔及利亚'),
Country('AD', '安道尔'),
Country('AO', '安哥拉'),
Country('AG', '安提瓜和巴布达'),
Country('AR', '阿根廷'),
Country('AM', '亚美尼亚'),
Country('AU', '澳大利亚'),
Country('AT', '奥地利'),
Country('AZ', '阿塞拜疆'),
Country('BS', '巴哈马'),
Country('BH', '巴林'),
Country('BD', '孟加拉国'),
Country('BB', '巴巴多斯'),
Country('BY', '白俄罗斯'),
Country('BE', '比利时'),
Country('BZ', '伯利兹'),
Country('BJ', '贝宁'),
Country('BT', '不丹'),
Country('BO', '玻利维亚'),
Country('BA', '波斯尼亚和黑塞哥维那'),
Country('BW', '博茨瓦纳'),
Country('BR', '巴西'),
Country('BN', '文莱'),
Country('BG', '保加利亚'),
Country('BF', '布基纳法索'),
Country('BI', '布隆迪'),
Country('CV', '佛得角'),
Country('KH', '柬埔寨'),
Country('CM', '喀麦隆'),
Country('CA', '加拿大'),
Country('CF', '中非共和国'),
Country('TD', '乍得'),
Country('CL', '智利'),
Country('CN', '中国'),
Country('CO', '哥伦比亚'),
Country('KM', '科摩罗'),
Country('CG', '刚果(刚果-布拉柴维尔)'),
Country('CR', '哥斯达黎加'),
Country('HR', '克罗地亚'),
Country('CU', '古巴'),
Country('CY', '塞浦路斯'),
Country('CZ', '捷克共和国'),
Country('DK', '丹麦'),
Country('DJ', '吉布提'),
Country('DM', '多米尼克'),
Country('DO', '多米尼加共和国'),
Country('TL', '东帝汶'),
Country('EC', '厄瓜多尔'),
Country('EG', '埃及'),
Country('SV', '萨尔瓦多'),
Country('GQ', '赤道几内亚'),
Country('ER', '厄立特里亚'),
Country('EE', '爱沙尼亚'),
Country('SZ', '斯威士兰'),
Country('ET', '埃塞俄比亚'),
Country('FJ', '斐济'),
Country('FI', '芬兰'),
Country('FR', '法国'),
Country('GA', '加蓬'),
Country('GM', '冈比亚'),
Country('GE', '格鲁吉亚'),
Country('DE', '德国'),
Country('GH', '加纳'),
Country('GR', '希腊'),
Country('GD', '格林纳达'),
Country('GT', '危地马拉'),
Country('GN', '几内亚'),
Country('GW', '几内亚比绍'),
Country('GY', '圭亚那'),
Country('HT', '海地'),
Country('HN', '洪都拉斯'),
Country('HU', '匈牙利'),
Country('IS', '冰岛'),
Country('IN', '印度'),
Country('ID', '印度尼西亚'),
Country('IR', '伊朗'),
Country('IQ', '伊拉克'),
Country('IE', '爱尔兰'),
Country('IL', '以色列'),
Country('IT', '意大利'),
Country('JM', '牙买加'),
Country('JP', '日本'),
Country('JO', '约旦'),
Country('KZ', '哈萨克斯坦'),
Country('KE', '肯尼亚'),
Country('KI', '基里巴斯'),
Country('KP', '朝鲜'),
Country('KR', '韩国'),
Country('XK', '科索沃'),
Country('KW', '科威特'),
Country('KG', '吉尔吉斯斯坦'),
Country('LA', '老挝'),
Country('LV', '拉脱维亚'),
Country('LB', '黎巴嫩'),
Country('LS', '莱索托'),
Country('LR', '利比里亚'),
Country('LY', '利比亚'),
Country('LI', '列支敦士登'),
Country('LT', '立陶宛'),
Country('LU', '卢森堡'),
Country('MG', '马达加斯加'),
Country('MW', '马拉维'),
Country('MY', '马来西亚'),
Country('MV', '马尔代夫'),
Country('ML', '马里'),
Country('MT', '马耳他'),
Country('MH', '马绍尔群岛'),
Country('MR', '毛里塔尼亚'),
Country('MU', '毛里求斯'),
Country('MX', '墨西哥'),
Country('FM', '密克罗尼西亚联邦'),
Country('MD', '摩尔多瓦'),
Country('MC', '摩纳哥'),
Country('MN', '蒙古'),
Country('ME', '黑山'),
Country('MA', '摩洛哥'),
Country('MZ', '莫桑比克'),
Country('MM', '缅甸'),
Country('NA', '纳米比亚'),
Country('NR', '瑙鲁'),
Country('NP', '尼泊尔'),
Country('NL', '荷兰'),
Country('NZ', '新西兰'),
Country('NI', '尼加拉瓜'),
Country('NE', '尼日尔'),
Country('NG', '尼日利亚'),
Country('MK', '北马其顿'),
Country('NO', '挪威'),
Country('OM', '阿曼'),
Country('PK', '巴基斯坦'),
Country('PW', '帕劳'),
Country('PA', '巴拿马'),
Country('PG', '巴布亚新几内亚'),
Country('PY', '巴拉圭'),
Country('PE', '秘鲁'),
Country('PH', '菲律宾'),
Country('PL', '波兰'),
Country('PT', '葡萄牙'),
Country('QA', '卡塔尔'),
Country('RO', '罗马尼亚'),
Country('RU', '俄罗斯'),
Country('RW', '卢旺达'),
Country('KN', '圣基茨和尼维斯'),
Country('LC', '圣卢西亚'),
Country('VC', '圣文森特和格林纳丁斯'),
Country('WS', '萨摩亚'),
Country('SM', '圣马力诺'),
Country('ST', '圣多美和普林西比'),
Country('SA', '沙特阿拉伯'),
Country('SN', '塞内加尔'),
Country('RS', '塞尔维亚'),
Country('SC', '塞舌尔'),
Country('SL', '塞拉利昂'),
Country('SG', '新加坡'),
Country('SK', '斯洛伐克'),
Country('SI', '斯洛文尼亚'),
Country('SB', '所罗门群岛'),
Country('SO', '索马里'),
Country('ZA', '南非'),
Country('SS', '南苏丹'),
Country('ES', '西班牙'),
Country('LK', '斯里兰卡'),
Country('SD', '苏丹'),
Country('SR', '苏里南'),
Country('SE', '瑞典'),
Country('CH', '瑞士'),
Country('SY', '叙利亚'),
Country('TW', '台湾'),
Country('TJ', '塔吉克斯坦'),
Country('TZ', '坦桑尼亚'),
Country('TH', '泰国'),
Country('TG', '多哥'),
Country('TO', '汤加'),
Country('TT', '特立尼达和多巴哥'),
Country('TN', '突尼斯'),
Country('TR', '土耳其'),
Country('TM', '土库曼斯坦'),
Country('TV', '图瓦卢'),
Country('UG', '乌干达'),
Country('UA', '乌克兰'),
Country('AE', '阿拉伯联合酋长国'),
Country('GB', '英国'),
Country('US', '美国'),
Country('UY', '乌拉圭'),
Country('UZ', '乌兹别克斯坦'),
Country('VU', '瓦努阿图'),
Country('VA', '梵蒂冈城'),
Country('VE', '委内瑞拉'),
Country('VN', '越南'),
Country('YE', '也门'),
Country('ZM', '赞比亚'),
Country('ZW', '津巴布韦'),
];
更多关于Flutter日历管理插件emor_calendar的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter日历管理插件emor_calendar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
emor_calendar
是一个用于 Flutter 的日历管理插件,它可以帮助你在应用中轻松地集成日历功能。以下是使用 emor_calendar
的基本步骤和示例代码。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 emor_calendar
插件的依赖。
dependencies:
flutter:
sdk: flutter
emor_calendar: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入包
在你的 Dart 文件中导入 emor_calendar
包。
import 'package:emor_calendar/emor_calendar.dart';
3. 使用日历组件
emor_calendar
提供了 EmorCalendar
组件,你可以直接在应用中使用它。
import 'package:flutter/material.dart';
import 'package:emor_calendar/emor_calendar.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Emor Calendar Example'),
),
body: EmorCalendar(
onDaySelected: (DateTime selectedDate) {
print('Selected date: $selectedDate');
},
),
),
);
}
}
4. 自定义日历
EmorCalendar
组件提供了多种自定义选项,例如设置初始日期、选择范围、自定义样式等。
EmorCalendar(
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime(2030),
selectedDayColor: Colors.blue,
todayColor: Colors.green,
onDaySelected: (DateTime selectedDate) {
print('Selected date: $selectedDate');
},
);
5. 处理事件
你可以通过 onDaySelected
回调来处理用户选择的日期。
EmorCalendar(
onDaySelected: (DateTime selectedDate) {
// 在这里处理选择的日期
print('Selected date: $selectedDate');
},
);
6. 其他功能
emor_calendar
还支持其他功能,例如:
- 多选日期:通过设置
selectedDates
和onDatesSelected
回调来实现多选日期。 - 自定义样式:通过
calendarStyle
参数来自定义日历的样式。
EmorCalendar(
calendarStyle: CalendarStyle(
selectedColor: Colors.blue,
todayColor: Colors.green,
weekendTextStyle: TextStyle(color: Colors.red),
),
);
7. 示例代码
以下是一个完整的示例代码,展示了如何使用 emor_calendar
插件。
import 'package:flutter/material.dart';
import 'package:emor_calendar/emor_calendar.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Emor Calendar Example'),
),
body: EmorCalendar(
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime(2030),
selectedDayColor: Colors.blue,
todayColor: Colors.green,
onDaySelected: (DateTime selectedDate) {
print('Selected date: $selectedDate');
},
),
),
);
}
}