fanguangyong 4 years ago
parent 0f86c621a0
commit a881182be2

@ -1,26 +1,2 @@
### 近期修改
### [2.0.0] - 2019/11/01
* 日历支持padding和margin属性item的大小计算修改
* 实现日历整体自适应高度
* controller提供changeExtraDataMap的方法可以随时动态的修改自定义数据extraDataMap
* 支持显示月视图和周视图的情况优先显示周视图MODE_SHOW_WEEK_AND_MONTH
* 支持verticalSpacing和itemSize属性
### [1.0.0] - 2019/10/10
* 重构日历的代码,进行性能优化
* 创建configuration类将配置的信息放到这里
* 引入provider状态管理,避免深层嵌套传递信息
* 实现周视图,并实现周视图和月视图之间的联动
* DateModel增加isCurrentMonth用于绘制月视图可以屏蔽一些非当前月份的日子前面几天或者后面几天的isCurrentMonth是为false的。
### [0.0.1] - 2019/5/19.
* 支持公历,农历,节气,传统节日,常用节假日
* 日期范围设置默认支持的最大日期范围为1971.01-2055.12
* 禁用日期范围设置,比如想实现某范围的日期内可以点击,范围外的日期置灰
* 支持单选、多选模式,提供多选超过限制个数的回调和多选超过指定范围的回调。
* 跳转到指定日期,默认支持动画切换
* 自定义日历Item支持组合widget的方式和利用canvas绘制的方式
* 自定义顶部的WeekBar
* 可以给Item添加自定义的额外数据实现各种额外的功能。比如实现进度条风格的日历
## [1.0.1]
- 新增多选范围功能

@ -1,138 +1,33 @@
## flutter_custom_calendar
> 本插件是基于[flutter_custom_calendar](https://github.com/fluttercandies/flutter_custom_calendar)做了稍微的修改进行上传的。
## FlutterCalendarWidget
具体使用方法见[flutter_custom_calendar](https://github.com/ifgyong/flutter_custom_calendar)
Flutter上的一个日历控件可以定制成自己想要的样子。
新增一个选择`mode`
Language: [English](README_en.md)|中文简体
支持选择开始和结束,选择范围内的日期,使用方法
- [FlutterCalendarWidget](#fluttercalendarwidget)
- [概述](#%e6%a6%82%e8%bf%b0)
- [在线Demo](#%e5%9c%a8%e7%ba%bfdemo)
- [效果图](#%e6%95%88%e6%9e%9c%e5%9b%be)
- [使用](#%e4%bd%bf%e7%94%a8)
- [2.0版本](#20%e7%89%88%e6%9c%ac)
- [注意事项](#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9)
- [主要API文档](#%e4%b8%bb%e8%a6%81api%e6%96%87%e6%a1%a3)
### 概述
* 支持公历,农历,节气,传统节日,常用节假日
* 日期范围设置默认支持的最大日期范围为1971.01-2055.12
* 禁用日期范围设置,比如想实现某范围的日期内可以点击,范围外的日期置灰
* 支持单选、多选模式,提供多选超过限制个数的回调和多选超过指定范围的回调。
* 跳转到指定日期,默认支持动画切换
* 自定义日历Item支持组合widget的方式和利用canvas绘制的方式
* 自定义顶部的WeekBar
* 根据实际场景可以给Item添加自定义的额外数据实现各种额外的功能。比如实现进度条风格的日历实现日历的各种标记
* 支持周视图的展示,支持月份视图和星期视图的展示与切换联动
### 在线Demo
日历支持web预览[点击此处进入预览](https://lxd312569496.github.io/flutter_custom_calendar/#/)
### 效果图
<table>
<tbody>
<tr>
<td>
<img src="https://tva1.sinaimg.cn/large/006y8mN6ly1g8hjt66daxj30n01dsad5.jpg" width="280" height="620">
</td>
<td>
<img src="https://user-gold-cdn.xitu.io/2019/10/9/16db060ca77ecad2?w=828&h=1792&f=png&s=126261" width="280" height="620">
</td>
</tr>
<tr>
<td>
<img src="https://user-gold-cdn.xitu.io/2019/10/9/16db061203661eca?w=828&h=1792&f=png&s=157230" width="280" height="620">
</td>
<td>
<img src="https://user-gold-cdn.xitu.io/2019/10/9/16db0614e44b6e0d?w=828&h=1792&f=png&s=145423" width="280" height="620">
</td>
<td>
<img src="https://user-gold-cdn.xitu.io/2019/10/9/16db0619af4c854a?w=828&h=1792&f=png&s=129203" width="280" height="620">
</td>
</tr>
<tr>
<td>
<img src="https://user-gold-cdn.xitu.io/2019/10/9/16db061ef0ed35dd?w=828&h=1792&f=png&s=81260" width="280" height="620">
</td>
<td>
<img src="https://tva1.sinaimg.cn/large/006y8mN6ly1g8hji5yiqkj30u01sx0wy.jpg" width="280" height="620">
</td>
<td>
<img src="https://tva1.sinaimg.cn/large/006y8mN6ly1g8hjntithzj30u01sxtcl.jpg" width="280" height="620">
</td>
</tr>
</tbody>
</table>
## 使用
1.在pubspec.yaml文件里面添加依赖:
```
flutter_custom_calendar:
git:
url: https://github.com/LXD312569496/flutter_custom_calendar.git
```
2.导入flutter_custom_calendar库
```
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
```
3.创建CalendarViewWidget对象配置CalendarController
```
CalendarController controller= new CalendarController(
minYear: 2018,
minYearMonth: 1,
maxYear: 2020,
maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK);
CalendarViewWidget calendar= CalendarViewWidget(
calendarController: controller,
),
```
* boxDecoration用来配置整体的背景
* 利用CalendarController来配置一些数据并且可以通过CalendarController进行一些操作或者事件监听比如滚动到下一个月获取当前被选中的Item等等。
4.操作日历
```
controller.toggleExpandStatus();//月视图和周视图的切换
```
controller = new CalendarController(
minYear: 2019,
minYearMonth: 1,
maxYear: 2021,
maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK,
selectedDateTimeList: _selectedDate,
selectMode: CalendarSelectedMode.mutltiStartToEndSelect)
..addOnCalendarSelectListener((dateModel) {
_selectedModels.add(dateModel);
})
..addOnCalendarUnSelectListener((dateModel) {
if (_selectedModels.contains(dateModel)) {
_selectedModels.remove(dateModel);
}
});
```
controller.previousPage();//操作日历切换到上一页
```
```
controller.nextPage();//操作日历切换到下一页
```
## 2.0版本
主要改动:
* UI配置相关的参数移动到CalendarView的构造方法里面旧版本是在controller里面配置
* 日历支持padding和margin属性item的大小计算修改
* 实现日历整体自适应高度
* controller提供changeExtraDataMap的方法可以随时动态的修改自定义数据extraDataMap
* 支持显示月视图和周视图的情况优先显示周视图MODE_SHOW_WEEK_AND_MONTH
* 支持verticalSpacing和itemSize属性
## 注意事项
* 如果使用2.0之前的版本则需要将UI配置相关的参数移动到CalendarView的构造方法里面旧版本是在controller里面配置
* 暂时没有发现其他问题,如果有其他问题,可以跟我说一下。
* 如果你用这个库做了日历,可以将展示结果分享给我,我贴到文档上进行展示
## 主要API文档
`CalendarSelectedMode.mutltiStartToEndSelect`这个选择模式会选择开始和结束中间的 默认选择的。
[API Documentation](API.md)

36
example/.gitignore vendored

@ -1,36 +0,0 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

@ -0,0 +1,116 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

@ -0,0 +1,252 @@
<component name="libraryTable">
<library name="Dart Packages" type="DartPackagesLibraryType">
<properties>
<option name="packageNameToDirsMap">
<entry key="archive">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/archive-2.0.13/lib" />
</list>
</value>
</entry>
<entry key="args">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/args-1.6.0/lib" />
</list>
</value>
</entry>
<entry key="async">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/async-2.4.1/lib" />
</list>
</value>
</entry>
<entry key="boolean_selector">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/boolean_selector-2.0.0/lib" />
</list>
</value>
</entry>
<entry key="charcode">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/charcode-1.1.3/lib" />
</list>
</value>
</entry>
<entry key="collection">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/collection-1.14.12/lib" />
</list>
</value>
</entry>
<entry key="convert">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/convert-2.1.1/lib" />
</list>
</value>
</entry>
<entry key="crypto">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/crypto-2.1.4/lib" />
</list>
</value>
</entry>
<entry key="cupertino_icons">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/cupertino_icons-0.1.3/lib" />
</list>
</value>
</entry>
<entry key="flutter">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/packages/flutter/lib" />
</list>
</value>
</entry>
<entry key="flutter_custom_calendar">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/flutter_custom_calendar-1.0.1/lib" />
</list>
</value>
</entry>
<entry key="flutter_test">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/packages/flutter_test/lib" />
</list>
</value>
</entry>
<entry key="image">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/image-2.1.12/lib" />
</list>
</value>
</entry>
<entry key="matcher">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/matcher-0.12.6/lib" />
</list>
</value>
</entry>
<entry key="meta">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/meta-1.1.8/lib" />
</list>
</value>
</entry>
<entry key="nested">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/nested-0.0.4/lib" />
</list>
</value>
</entry>
<entry key="path">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/path-1.6.4/lib" />
</list>
</value>
</entry>
<entry key="petitparser">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/petitparser-2.4.0/lib" />
</list>
</value>
</entry>
<entry key="provider">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/provider-4.1.3/lib" />
</list>
</value>
</entry>
<entry key="quiver">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/quiver-2.1.3/lib" />
</list>
</value>
</entry>
<entry key="sky_engine">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/pkg/sky_engine/lib" />
</list>
</value>
</entry>
<entry key="source_span">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/source_span-1.7.0/lib" />
</list>
</value>
</entry>
<entry key="stack_trace">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/stack_trace-1.9.3/lib" />
</list>
</value>
</entry>
<entry key="stream_channel">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/stream_channel-2.0.0/lib" />
</list>
</value>
</entry>
<entry key="string_scanner">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/string_scanner-1.0.5/lib" />
</list>
</value>
</entry>
<entry key="term_glyph">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/term_glyph-1.1.0/lib" />
</list>
</value>
</entry>
<entry key="test_api">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/test_api-0.2.15/lib" />
</list>
</value>
</entry>
<entry key="typed_data">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/typed_data-1.1.6/lib" />
</list>
</value>
</entry>
<entry key="vector_math">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/vector_math-2.0.8/lib" />
</list>
</value>
</entry>
<entry key="xml">
<value>
<list>
<option value="$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/xml-3.6.1/lib" />
</list>
</value>
</entry>
</option>
</properties>
<CLASSES>
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/archive-2.0.13/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/args-1.6.0/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/async-2.4.1/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/boolean_selector-2.0.0/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/charcode-1.1.3/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/collection-1.14.12/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/convert-2.1.1/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/crypto-2.1.4/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/cupertino_icons-0.1.3/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/flutter_custom_calendar-1.0.1/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/image-2.1.12/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/matcher-0.12.6/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/meta-1.1.8/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/nested-0.0.4/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/path-1.6.4/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/petitparser-2.4.0/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/provider-4.1.3/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/quiver-2.1.3/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/source_span-1.7.0/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/stack_trace-1.9.3/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/stream_channel-2.0.0/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/string_scanner-1.0.5/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/term_glyph-1.1.0/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/test_api-0.2.15/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/typed_data-1.1.6/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/vector_math-2.0.8/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/.pub-cache/hosted/pub.flutter-io.cn/xml-3.6.1/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/pkg/sky_engine/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/packages/flutter/lib" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/packages/flutter_test/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

@ -0,0 +1,29 @@
<component name="libraryTable">
<library name="Dart SDK">
<CLASSES>
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/async" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/cli" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/collection" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/convert" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/core" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/developer" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/ffi" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/html" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/indexed_db" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/io" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/isolate" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/js" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/js_util" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/math" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/mirrors" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/svg" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/typed_data" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/wasm" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/web_audio" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/web_gl" />
<root url="file://$USER_HOME$/flutterSDK/flutter1.17-stable/bin/cache/dart-sdk/lib/web_sql" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

@ -0,0 +1,7 @@
<component name="libraryTable">
<library name="Flutter Plugins" type="FlutterPluginsLibraryType">
<CLASSES />
<JAVADOC />
<SOURCES />
</library>
</component>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/example.iml" filepath="$PROJECT_DIR$/.idea/example.iml" />
</modules>
</component>
</project>

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="712d3fab-fb14-4aa9-8f22-6e18487dd55c" name="Default Changelist" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="Nexus_5_API_28" />
<component name="ProjectId" id="1dNihvP9QVilHtN46zdzXsNhST3" />
<component name="PropertiesComponent">
<property name="dart.analysis.tool.window.force.activate" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="show.migrate.to.gradle.popup" value="false" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration name="main.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="filePath" value="$PROJECT_DIR$/lib/main.dart" />
<method v="2" />
</configuration>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="712d3fab-fb14-4aa9-8f22-6e18487dd55c" name="Default Changelist" comment="" />
<created>1592272073156</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1592272073156</updated>
</task>
<servers />
</component>
</project>

@ -1,10 +0,0 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 0120c414fbc5d11c503e2091f420c02ffd6dda67
channel: master
project_type: app

@ -1,6 +1,6 @@
# example1
# example
A new Flutter project.
flutter_custom_calendar/example
## Getting Started

@ -22,28 +22,22 @@ if (flutterVersionName == null) {
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.example1"
applicationId "com.example.example"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@ -58,10 +52,3 @@ android {
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example1">
package="com.example.example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example1">
package="com.example.example">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
@ -7,7 +7,7 @@
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="example1"
android:label="example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
@ -16,17 +16,32 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

@ -0,0 +1,6 @@
package com.example.example;
import io.flutter.embedding.android.FlutterActivity;
public class MainActivity extends FlutterActivity {
}

@ -1,12 +0,0 @@
package com.example.example1
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
}
}

@ -1,8 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@android:color/white</item>
</style>
</resources>

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example1">
package="com.example.example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->

@ -1,5 +1,4 @@
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
@ -7,7 +6,6 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/app/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/app/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/app/src/main/assets" />
<option name="LIBS_FOLDER_RELATIVE_PATH" value="/app/src/main/libs" />
<option name="PROGUARD_LOGS_FOLDER_RELATIVE_PATH" value="/app/src/main/proguard_logs" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/app/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Flutter for Android" level="project" />
</component>
</module>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
</component>
</module>

@ -136,7 +136,7 @@
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "The Chromium Authors";
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
@ -145,7 +145,7 @@
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@ -308,7 +308,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example1;
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
@ -442,7 +442,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example1;
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -469,7 +469,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example1;
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

@ -11,7 +11,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>example1</string>
<string>example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>

@ -1 +1 @@
#import "GeneratedPluginRegistrant.h"
#import "GeneratedPluginRegistrant.h"

@ -1,253 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
class BlueStylePage extends StatefulWidget {
BlueStylePage({Key key, this.title}) : super(key: key);
final String title;
@override
_BlueStylePageState createState() => _BlueStylePageState();
}
class _BlueStylePageState extends State<BlueStylePage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
Map<DateModel, String> customExtraData = {};
@override
void initState() {
super.initState();
controller = new CalendarController(
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK,
extraDataMap: customExtraData);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
var calendarWidget = CalendarViewWidget(
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return CustomStyleDayWidget(dateModel);
},
calendarController: controller,
boxDecoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
color: Colors.white,
),
padding: EdgeInsets.only(left: 20, right: 20, bottom: 10),
margin: const EdgeInsets.only(
left: 15,
right: 15,
),
);
return SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: Color(0xff6219EC),
),
backgroundColor: Color(0xff6219EC),
body: new Container(
child: new Column(
children: <Widget>[
SizedBox(
height: 20,
),
Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
height: 100,
margin: const EdgeInsets.only(left: 15, right: 15),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
color: Colors.white),
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 30),
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "Februaly",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
fontSize: 30),
),
TextSpan(
text: " 2019",
style: TextStyle(
color: Colors.black, fontSize: 30),
),
],
),
),
),
],
),
),
calendarWidget
],
),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: new Text(selectText.value),
);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.toggleExpandStatus();
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["mo", "tu", "we", "th", "fr", "sa", "su"];
//build
@override
Widget build(BuildContext context) {
List<Widget> children = List();
var items = getWeekDayWidget();
children.add(Row(
children: items,
));
children.add(Divider(
color: Colors.grey,
));
return Column(
children: children,
);
}
@override
Widget getWeekBarItem(int index) {
return new Container(
margin: EdgeInsets.only(top: 10, bottom: 10),
child: new Center(
child: new Text(
weekList[index],
style:
TextStyle(fontWeight: FontWeight.w700, color: Color(0xffC5BCDC)),
),
),
);
}
}
class CustomStyleDayWidget extends BaseCombineDayWidget {
CustomStyleDayWidget(DateModel dateModel) : super(dateModel);
final TextStyle normalTextStyle =
TextStyle(fontWeight: FontWeight.w700, color: Colors.black);
final TextStyle noIsCurrentMonthTextStyle =
TextStyle(fontWeight: FontWeight.w700, color: Colors.grey);
@override
Widget getNormalWidget(DateModel dateModel) {
return Container(
margin: EdgeInsets.all(8),
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
//
new Expanded(
child: Center(
child: new Text(
dateModel.day.toString(),
style: dateModel.isCurrentMonth
? normalTextStyle
: noIsCurrentMonthTextStyle,
),
),
),
],
),
],
),
);
}
@override
Widget getSelectedWidget(DateModel dateModel) {
return Container(
// margin: EdgeInsets.all(8),
decoration: new BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(5),
),
color: Color(0xffFED32B),
),
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
//
new Expanded(
child: Center(
child: new Text(
dateModel.day.toString(),
style: dateModel.isCurrentMonth
? normalTextStyle
: noIsCurrentMonthTextStyle,
),
),
),
],
),
],
),
);
}
}

@ -1,192 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
/**
* +
*/
class CustomOffsetPage extends StatefulWidget {
CustomOffsetPage({Key key, this.title}) : super(key: key);
final String title;
@override
_CustomOffsetPageState createState() => _CustomOffsetPageState();
}
class _CustomOffsetPageState extends State<CustomOffsetPage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
@override
void initState() {
super.initState();
controller = new CalendarController(
offset: 5
);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
controller.moveToPreviousMonth();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
controller.moveToNextMonth();
}),
],
),
CalendarViewWidget(
calendarController: controller,
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return CustomStyleDayWidget(dateModel);
}
),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["", "", "", "", "", "", ""];
@override
Widget getWeekBarItem(int index) {
return new Container(
child: new Center(
child: new Text(weekList[index]),
),
);
}
}
class CustomStyleDayWidget extends BaseCustomDayWidget {
CustomStyleDayWidget(DateModel dateModel) : super(dateModel);
@override
void drawNormal(DateModel dateModel, Canvas canvas, Size size) {
// if (!dateModel.isCurrentMonth) {
// return;
// }
bool isWeekend = dateModel.isWeekend;
bool isInRange = dateModel.isInRange;
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(
color: !isInRange
? Colors.grey
: isWeekend ? Colors.blue : Colors.black,
fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(
color: !isInRange
? Colors.grey
: isWeekend ? Colors.blue : Colors.grey,
fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
@override
void drawSelected(DateModel dateModel, Canvas canvas, Size size) {
// if (!dateModel.isCurrentMonth) {
// return;
// }
//
Paint backGroundPaint = new Paint()
..color = Colors.blue
..strokeWidth = 2;
double padding = 8;
canvas.drawCircle(Offset(size.width / 2, size.height / 2),
(size.width - padding) / 2, backGroundPaint);
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(color: Colors.white, fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(color: Colors.white, fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
}

@ -1,244 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/style/style.dart';
import 'package:random_pk/random_pk.dart';
/**
*
*/
class CustomSignPage extends StatefulWidget {
CustomSignPage({Key key, this.title}) : super(key: key);
final String title;
@override
_CustomSignPageState createState() => _CustomSignPageState();
}
class _CustomSignPageState extends State<CustomSignPage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
Map<DateModel, String> customExtraData = {
DateModel.fromDateTime(DateTime.now().add(Duration(days: -1))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: -2))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: -3))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: -4))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: -5))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: -6))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: -7))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: -8))): "",
DateModel.fromDateTime(DateTime.now()): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 1))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 2))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 3))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 4))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 5))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 6))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 7))): "",
DateModel.fromDateTime(DateTime.now().add(Duration(days: 8))): "",
};
@override
void initState() {
super.initState();
controller = new CalendarController(
extraDataMap: customExtraData);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
controller.moveToPreviousMonth();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
controller.moveToNextMonth();
}),
],
),
CalendarViewWidget(
calendarController: controller,
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return CustomStyleDayWidget(dateModel);
},
),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.toggleExpandStatus();
// controller.changeExtraData({});
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["", "", "", "", "", "", ""];
@override
Widget getWeekBarItem(int index) {
return new Container(
child: new Center(
child: new Text(weekList[index]),
),
);
}
}
class CustomStyleDayWidget extends BaseCombineDayWidget {
CustomStyleDayWidget(DateModel dateModel) : super(dateModel);
@override
Widget getNormalWidget(DateModel dateModel) {
if (!dateModel.isCurrentMonth) {
return Container();
}
return Container(
margin: EdgeInsets.all(8),
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
//
new Expanded(
child: Center(
child: new Text(
dateModel.day.toString(),
style: currentMonthTextStyle,
),
),
),
//
new Expanded(
child: Center(
child: new Text(
"${dateModel.lunarString}",
style: lunarTextStyle,
),
),
),
],
),
dateModel.extraData != null
? Positioned(
child: Text(
"${dateModel.extraData}",
style: TextStyle(fontSize: 10, color: RandomColor.next()),
),
right: 0,
top: 0,
)
: Container()
],
),
);
}
@override
Widget getSelectedWidget(DateModel dateModel) {
if (!dateModel.isCurrentMonth) {
return Container();
}
return Container(
margin: EdgeInsets.all(8),
foregroundDecoration:
new BoxDecoration(border: Border.all(width: 2, color: Colors.blue)),
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
//
new Expanded(
child: Center(
child: new Text(
dateModel.day.toString(),
style: currentMonthTextStyle,
),
),
),
//
new Expanded(
child: Center(
child: new Text(
"${dateModel.lunarString}",
style: lunarTextStyle,
),
),
),
],
),
dateModel.extraData != null
? Positioned(
child: Text(
"${dateModel.extraData}",
style: TextStyle(fontSize: 10, color: RandomColor.next()),
),
right: 0,
top: 0,
)
: Container()
],
),
);
}
}

@ -1,190 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
/**
* +
*/
class CustomStylePage extends StatefulWidget {
CustomStylePage({Key key, this.title}) : super(key: key);
final String title;
@override
_CustomStylePageState createState() => _CustomStylePageState();
}
class _CustomStylePageState extends State<CustomStylePage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
@override
void initState() {
super.initState();
controller = new CalendarController(
selectDateModel: DateModel.fromDateTime(DateTime.now()));
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
controller.moveToPreviousMonth();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
controller.moveToNextMonth();
}),
],
),
CalendarViewWidget(
calendarController: controller,
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return CustomStyleDayWidget(dateModel);
}),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["", "", "", "", "", "", ""];
@override
Widget getWeekBarItem(int index) {
return new Container(
child: new Center(
child: new Text(weekList[index]),
),
);
}
}
class CustomStyleDayWidget extends BaseCustomDayWidget {
CustomStyleDayWidget(DateModel dateModel) : super(dateModel);
@override
void drawNormal(DateModel dateModel, Canvas canvas, Size size) {
if (!dateModel.isCurrentMonth) {
return;
}
bool isWeekend = dateModel.isWeekend;
bool isInRange = dateModel.isInRange;
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(
color: !isInRange
? Colors.grey
: isWeekend ? Colors.blue : Colors.black,
fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(
color: !isInRange
? Colors.grey
: isWeekend ? Colors.blue : Colors.grey,
fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
@override
void drawSelected(DateModel dateModel, Canvas canvas, Size size) {
if (!dateModel.isCurrentMonth) {
return;
}
//
Paint backGroundPaint = new Paint()
..color = Colors.blue
..strokeWidth = 2;
double padding = 8;
canvas.drawCircle(Offset(size.width / 2, size.height / 2),
(size.width - padding) / 2, backGroundPaint);
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(color: Colors.white, fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(color: Colors.white, fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
}

@ -1,102 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
/**
* +
*/
class DefaultStylePage extends StatefulWidget {
DefaultStylePage({Key key, this.title}) : super(key: key);
final String title;
@override
_DefaultStylePageState createState() => _DefaultStylePageState();
}
class _DefaultStylePageState extends State<DefaultStylePage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
@override
void initState() {
super.initState();
DateTime now = DateTime.now();
controller = new CalendarController(
minYear: now.year - 1,
minYearMonth: 1,
maxYear: now.year + 1,
maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
// controller.moveToPreviousMonth();
controller.previousPage();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
// controller.moveToNextMonth();
controller.nextPage();
}),
],
),
CalendarViewWidget(
calendarController: controller,
),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.toggleExpandStatus();
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}

@ -1,19 +1,12 @@
import 'package:example1/custom_offset_page.dart';
import 'dart:collection';
import 'only_week_page.dart';
import 'red_style_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'blue_style_page.dart';
import 'custom_sign_page.dart';
import 'custom_style_page.dart';
import 'default_style_page.dart';
import 'multi_select_style_page.dart';
import 'progress_style_page.dart';
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/controller.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
void main() {
// debugProfileBuildsEnabled=true;
// debugProfilePaintsEnabled=true;
// debugPrintRebuildDirtyWidgets=true;
runApp(MyApp());
}
@ -22,98 +15,162 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// checkerboardOffscreenLayers: true, // 使saveLayer
routes: <String, WidgetBuilder>{
"/default": (context) => DefaultStylePage(
title: "默认风格+单选",
),
"/custom": (context) => CustomStylePage(
title: "自定义风格+单选",
),
"/multi_select": (context) => MultiSelectStylePage(
title: "自定义风格+多选",
),
"/progress": (context) => ProgressStylePage(
title: "进度条风格+单选",
),
"/custom_sign": (context) => CustomSignPage(
title: "自定义额外数据,实现标记功能",
),
"/only_week_view": (context) => OnlyWeekPage(
title: "仅显示周视图",
),
"/blue_style_page": (context) => BlueStylePage(title: "蓝色背景Demo"),
"/red_style_page": (context) => RedStylePage(title: "蓝色背景Demo"),
"/custom_offset_page": (context) => CustomOffsetPage(title: "自定义偏移量"),
},
title: 'Flutter Demo',
theme: ThemeData(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage());
visualDensity: VisualDensity.adaptivePlatformDensity,
focusColor: Colors.teal),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class HomePage extends StatelessWidget {
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CalendarController controller;
CalendarViewWidget calendar;
HashSet<DateTime> _selectedDate = new HashSet();
HashSet<DateModel> _selectedModels = new HashSet();
@override
void initState() {
_selectedDate.add(DateTime.now());
controller = new CalendarController(
minYear: 2019,
minYearMonth: 1,
maxYear: 2021,
maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK,
selectedDateTimeList: _selectedDate,
selectMode: CalendarSelectedMode.singleSelect)
..addOnCalendarSelectListener((dateModel) {
_selectedModels.add(dateModel);
setState(() {
_selectDate = _selectedModels.toString();
});
})
..addOnCalendarUnSelectListener((dateModel) {
if (_selectedModels.contains(dateModel)) {
_selectedModels.remove(dateModel);
}
setState(() {
_selectDate = '';
});
});
calendar = new CalendarViewWidget(
calendarController: controller,
dayWidgetBuilder: (DateModel model) {
double wd = (MediaQuery.of(context).size.width - 20) / 7;
bool _isSelected = model.isSelected;
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(wd / 2)),
child: Container(
color: _isSelected ? Theme.of(context).focusColor : Colors.white,
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
model.day.toString(),
style: TextStyle(
color: model.isCurrentMonth
? (_isSelected == false
? (model.isWeekend
? Colors.black38
: Colors.black87)
: Colors.white)
: Colors.black38),
),
// Text(model.lunarDay.toString()),
],
),
),
);
},
);
super.initState();
}
String _selectDate = '';
@override
Widget build(BuildContext context) {
return new Scaffold(
body: SafeArea(
child: new Column(
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/default");
},
child: new Text("默认风格+单选"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/custom");
},
child: new Text("自定义风格+单选"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/multi_select");
},
child: new Text("自定义风格+多选"),
Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.start,
children: <Widget>[
Text('请选择mode'),
FlatButton(
child: Text(
'singleSelect',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.singleSelect;
});
},
color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.singleSelect
? Colors.teal
: Colors.black38,
),
FlatButton(
child: Text(
'multiSelect',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.multiSelect;
});
},
color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.multiSelect
? Colors.teal
: Colors.black38,
),
FlatButton(
child: Text(
'mutltiStartToEndSelect',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.mutltiStartToEndSelect;
});
},
color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.mutltiStartToEndSelect
? Colors.teal
: Colors.black38,
)
],
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/progress");
},
child: new Text("进度条风格+单选"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/custom_sign");
},
child: new Text("自定义额外数据,实现标记功能"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/only_week_view");
},
child: new Text("仅显示周视图"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/blue_style_page");
},
child: new Text("蓝色Demo"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/red_style_page");
},
child: new Text("红色Demo"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/custom_offset_page");
},
child: new Text("自定义偏移量"),
calendar,
Expanded(
child: Text(
' $_selectDate ',
style: TextStyle(color: Theme.of(context).focusColor),
),
)
],
),

@ -1,185 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
/**
* +
*/
class MultiSelectStylePage extends StatefulWidget {
MultiSelectStylePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MultiSelectStylePageState createState() => _MultiSelectStylePageState();
}
class _MultiSelectStylePageState extends State<MultiSelectStylePage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
@override
void initState() {
super.initState();
controller = new CalendarController(
selectMode: CalendarConstants.MODE_MULTI_SELECT,
maxMultiSelectCount: 5,
minSelectYear: 2019,
minSelectMonth: 5,
minSelectDay: 20,
selectedDateTimeList: {
DateTime.now(),
}
);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"多选模式\n选中的时间:\n${controller.getMultiSelectCalendar().join("\n")}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"多选模式\n选中的时间:\n${controller.getMultiSelectCalendar().join("\n")}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
controller.moveToPreviousMonth();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
controller.moveToNextMonth();
}),
],
),
CalendarViewWidget(
calendarController: controller,
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return CustomStyleDayWidget(dateModel);
}),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["", "", "", "", "", "", ""];
@override
Widget getWeekBarItem(int index) {
return new Container(
child: new Center(
child: new Text(weekList[index]),
),
);
}
}
class CustomStyleDayWidget extends BaseCustomDayWidget {
CustomStyleDayWidget(DateModel dateModel) : super(dateModel);
@override
void drawNormal(DateModel dateModel, Canvas canvas, Size size) {
bool isInRange = dateModel.isInRange;
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(
color: !isInRange ? Colors.grey : Colors.black, fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(
color: !isInRange ? Colors.grey : Colors.grey, fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
@override
void drawSelected(DateModel dateModel, Canvas canvas, Size size) {
//
Paint backGroundPaint = new Paint()
..color = Colors.blue
..strokeWidth = 2;
double padding = 8;
canvas.drawCircle(Offset(size.width / 2, size.height / 2),
(size.width - padding) / 2, backGroundPaint);
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(color: Colors.white, fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(color: Colors.white, fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
}

@ -1,102 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
/**
* +
*/
class OnlyWeekPage extends StatefulWidget {
OnlyWeekPage({Key key, this.title}) : super(key: key);
final String title;
@override
_OnlyWeekPageState createState() => _OnlyWeekPageState();
}
class _OnlyWeekPageState extends State<OnlyWeekPage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
@override
void initState() {
super.initState();
DateTime now = DateTime.now();
controller = new CalendarController(
minYear: now.year,
minYearMonth: now.month - 2,
maxYear: now.year,
maxYearMonth: now.month + 1,
showMode: CalendarConstants.MODE_SHOW_ONLY_WEEK);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
// controller.moveToPreviousMonth();
controller.previousPage();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
// controller.moveToNextMonth();
controller.nextPage();
}),
],
),
CalendarViewWidget(
calendarController: controller,
),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.toggleExpandStatus();
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}

@ -1,224 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'dart:math';
/**
* +
*/
class ProgressStylePage extends StatefulWidget {
ProgressStylePage({Key key, this.title}) : super(key: key);
final String title;
@override
_ProgressStylePageState createState() => _ProgressStylePageState();
}
class _ProgressStylePageState extends State<ProgressStylePage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
@override
void initState() {
super.initState();
DateTime now = DateTime.now();
DateTime temp = DateTime(now.year, now.month, now.day);
Map<DateModel, int> progressMap = {
DateModel.fromDateTime(temp.add(Duration(days: -1))): 0,
DateModel.fromDateTime(temp.add(Duration(days: -2))): 20,
DateModel.fromDateTime(temp.add(Duration(days: -3))): 40,
DateModel.fromDateTime(temp.add(Duration(days: -4))): 60,
DateModel.fromDateTime(temp.add(Duration(days: -5))): 80,
DateModel.fromDateTime(temp.add(Duration(days: -6))): 100,
DateModel.fromDateTime(temp.add(Duration(days: 1))): 0,
DateModel.fromDateTime(temp.add(Duration(days: 2))): 20,
DateModel.fromDateTime(temp.add(Duration(days: 3))): 40,
DateModel.fromDateTime(temp.add(Duration(days: 4))): 60,
DateModel.fromDateTime(temp.add(Duration(days: 5))): 80,
DateModel.fromDateTime(temp.add(Duration(days: 6))): 100,
};
controller = new CalendarController(
extraDataMap: progressMap,
);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
controller.moveToPreviousMonth();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
controller.moveToNextMonth();
}),
],
),
CalendarViewWidget(
calendarController: controller,
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return ProgressStyleDayWidget(dateModel);
}),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["", "", "", "", "", "", ""];
@override
Widget getWeekBarItem(int index) {
return new Container(
child: new Center(
child: new Text(weekList[index]),
),
);
}
}
class ProgressStyleDayWidget extends BaseCustomDayWidget {
ProgressStyleDayWidget(DateModel dateModel) : super(dateModel);
@override
void drawNormal(DateModel dateModel, Canvas canvas, Size size) {
bool isInRange = dateModel.isInRange;
//
int progress = dateModel.extraData;
if (progress != null && progress != 0) {
double padding = 8;
Paint paint = Paint()
..color = Colors.grey
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.drawCircle(Offset(size.width / 2, size.height / 2),
(size.width - padding) / 2, paint);
paint.color = Colors.blue;
double startAngle = -90 * pi / 180;
double sweepAngle = pi / 180 * (360 * progress / 100);
canvas.drawArc(
Rect.fromCircle(
center: Offset(size.width / 2, size.height / 2),
radius: (size.width - padding) / 2),
startAngle,
sweepAngle,
false,
paint);
}
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(
color: !isInRange ? Colors.grey : Colors.black, fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(
color: !isInRange ? Colors.grey : Colors.grey, fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
@override
void drawSelected(DateModel dateModel, Canvas canvas, Size size) {
//
Paint backGroundPaint = new Paint()
..color = Colors.blue
..strokeWidth = 2;
double padding = 8;
canvas.drawCircle(Offset(size.width / 2, size.height / 2),
(size.width - padding) / 2, backGroundPaint);
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(color: Colors.white, fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(color: Colors.white, fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
}

@ -1,238 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
class RedStylePage extends StatefulWidget {
RedStylePage({Key key, this.title}) : super(key: key);
final String title;
@override
_RedStylePageState createState() => _RedStylePageState();
}
class _RedStylePageState extends State<RedStylePage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
Map<DateModel, String> customExtraData = {};
Color pinkColor = Color(0xffFF8291);
@override
void initState() {
super.initState();
controller = new CalendarController(
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK,
extraDataMap: customExtraData);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
var calendarWidget = CalendarViewWidget(
calendarController: controller,
margin: EdgeInsets.only(top: 20),
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return CustomStyleDayWidget(dateModel);
},
);
return SafeArea(
child: Scaffold(
appBar: AppBar(),
body: new Container(
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 20),
child: new Column(
crossAxisAlignment:CrossAxisAlignment.stretch ,
children: <Widget>[
SizedBox(
height: 20,
),
Stack(
alignment: Alignment.center,
children: <Widget>[
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(
"${text.value}",
style: TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w700),
);
}),
Positioned(
left: 0,
child: Icon(
Icons.notifications,
color: pinkColor,
),
),
Positioned(
right: 40,
child: Icon(
Icons.search,
color: pinkColor,
),
),
Positioned(
right: 0,
child: Icon(
Icons.add,
color: pinkColor,
),
),
],
),
calendarWidget,
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: new Text(selectText.value),
);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.toggleExpandStatus();
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["M", "T", "W", "T", "F", "S", "S"];
//build
@override
Widget build(BuildContext context) {
List<Widget> children = List();
var items = getWeekDayWidget();
children.add(Row(
children: items,
));
children.add(Divider(
color: Colors.grey,
));
return Column(
children: children,
);
}
@override
Widget getWeekBarItem(int index) {
return new Container(
margin: EdgeInsets.only(top: 10, bottom: 10),
child: new Center(
child: new Text(
weekList[index],
style:
TextStyle(fontWeight: FontWeight.w700, color: Color(0xffBBC0C6)),
),
),
);
}
}
class CustomStyleDayWidget extends BaseCombineDayWidget {
CustomStyleDayWidget(DateModel dateModel) : super(dateModel);
final TextStyle normalTextStyle =
TextStyle(fontWeight: FontWeight.w700, color: Colors.black);
final TextStyle noIsCurrentMonthTextStyle =
TextStyle(fontWeight: FontWeight.w700, color: Colors.grey);
@override
Widget getNormalWidget(DateModel dateModel) {
return Container(
margin: EdgeInsets.all(8),
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
//
new Expanded(
child: Center(
child: new Text(
dateModel.day.toString(),
style: dateModel.isCurrentMonth
? normalTextStyle
: noIsCurrentMonthTextStyle,
),
),
),
],
),
],
),
);
}
@override
Widget getSelectedWidget(DateModel dateModel) {
return Container(
// margin: EdgeInsets.all(8),
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: Color(0xffFF8291),
),
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
//
new Expanded(
child: Center(
child: new Text(
dateModel.day.toString(),
style: TextStyle(color: Colors.white),
),
),
),
],
),
],
),
);
}
}

@ -63,7 +63,7 @@ packages:
name: cupertino_icons
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.1.2"
version: "0.1.3"
flutter:
dependency: "direct main"
description: flutter
@ -72,10 +72,10 @@ packages:
flutter_custom_calendar:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.0.1"
name: flutter_custom_calendar
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.2"
flutter_test:
dependency: "direct dev"
description: flutter
@ -137,13 +137,6 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.3"
random_pk:
dependency: "direct main"
description:
name: random_pk
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.0.3"
sky_engine:
dependency: transitive
description: flutter

@ -1,5 +1,9 @@
name: example1
description: A new Flutter project.
name: example
description: flutter_custom_calendar example
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
@ -14,23 +18,23 @@ description: A new Flutter project.
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
random_pk: ^0.0.3
flutter_custom_calendar:
path: ../
cupertino_icons: ^0.1.3
flutter_custom_calendar: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
@ -44,8 +48,8 @@ flutter:
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.

@ -8,23 +8,21 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:example1/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
// testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// // Build our app and trigger a frame.
// await tester.pumpWidget(MyApp());
//
// // Verify that our counter starts at 0.
// expect(find.text('0'), findsOneWidget);
// expect(find.text('1'), findsNothing);
//
// // Tap the '+' icon and trigger a frame.
// await tester.tap(find.byIcon(Icons.add));
// await tester.pump();
//
// // Verify that our counter has incremented.
// expect(find.text('0'), findsNothing);
// expect(find.text('1'), findsOneWidget);
// });
}

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>example1</title>
</head>
<body>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart Packages" level="project" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
</component>
</module>

@ -1,4 +1,4 @@
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'model/date_model.dart';
/**
*
@ -12,6 +12,7 @@ class CacheData {
static CacheData get instance => _instance;
Map<DateModel, List<DateModel>> monthListCache = Map();
Map<DateModel, List<DateModel>> weekListCache = Map();
static CacheData getInstance() {
@ -21,14 +22,8 @@ class CacheData {
return _instance;
}
void clearData(){
void clearData() {
monthListCache.clear();
weekListCache.clear();
}
}

@ -2,13 +2,13 @@ import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/cache_data.dart';
import 'package:flutter_custom_calendar/configuration.dart';
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/controller.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:flutter_custom_calendar/widget/month_view.dart';
import 'configuration.dart';
import 'constants/constants.dart';
import 'flutter_custom_calendar.dart';
import 'utils/LogUtil.dart';
import 'utils/date_util.dart';
import 'model/date_model.dart';
/**
* provider
@ -173,7 +173,9 @@ class CalendarProvider extends ChangeNotifier {
calendarConfiguration.showMode ==
CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) {
int lineCount = DateUtil.getMonthViewLineCount(
calendarConfiguration.nowYear, calendarConfiguration.nowMonth, calendarConfiguration.offset);
calendarConfiguration.nowYear,
calendarConfiguration.nowMonth,
calendarConfiguration.offset);
totalHeight = calendarConfiguration.itemSize * (lineCount) +
calendarConfiguration.verticalSpacing * (lineCount - 1);
} else {

@ -1,16 +1,19 @@
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/controller.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter/foundation.dart';
import 'constants/constants.dart';
import 'flutter_custom_calendar.dart';
import 'model/date_model.dart';
/**
*
*/
class CalendarConfiguration {
//,MODE_SINGLE_SELECTMODE_MULTI_SELECT
int selectMode;
CalendarSelectedMode selectMode;
//
int showMode;
@ -60,6 +63,7 @@ class CalendarConfiguration {
//
OnMonthChange monthChange; // ,multiMonthChanges
OnCalendarSelect calendarSelect; //
OnCalendarSelect unCalendarSelect; //
OnMultiSelectOutOfRange multiSelectOutOfRange; //
OnMultiSelectOutOfSize multiSelectOutOfSize; //

@ -1,3 +1,5 @@
enum CalendarSelectedMode { singleSelect, multiSelect, mutltiStartToEndSelect }
class CalendarConstants {
//
//
@ -9,7 +11,7 @@ class CalendarConstants {
///
static const int MODE_MULTI_SELECT_FROM_TO_END = 3;
static const int MODE_MULTI_SELECT_START_TO_END = 3;
//
static const int MODE_SHOW_ONLY_MONTH = 1; //

@ -1,15 +1,17 @@
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:flutter_custom_calendar/configuration.dart';
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:flutter_custom_calendar/widget/default_combine_day_view.dart';
import 'package:flutter_custom_calendar/widget/default_custom_day_view.dart';
import 'package:flutter_custom_calendar/widget/default_week_bar.dart';
import 'calendar_provider.dart';
import 'configuration.dart';
import 'constants/constants.dart';
import 'flutter_custom_calendar.dart';
import 'utils/LogUtil.dart';
import 'utils/date_util.dart';
import 'widget/default_combine_day_view.dart';
import 'widget/default_custom_day_view.dart';
import 'widget/default_week_bar.dart';
import 'model/date_model.dart';
/**
* controller
@ -33,7 +35,7 @@ class CalendarController {
PageController weekController; //controller
CalendarController(
{int selectMode = CalendarConstants.MODE_SINGLE_SELECT,
{CalendarSelectedMode selectMode = CalendarSelectedMode.singleSelect,
int showMode = CalendarConstants.MODE_SHOW_ONLY_MONTH,
int minYear = 1971,
int maxYear = 2055,
@ -52,7 +54,7 @@ class CalendarController {
int maxMultiSelectCount = 9999,
Map<DateModel, Object> extraDataMap = EMPTY_MAP,
int offset = 0 //
}) {
}) {
assert(offset >= 0 && offset <= 6);
LogUtil.log(TAG: this.runtimeType, message: "init CalendarConfiguration");
//
@ -189,7 +191,7 @@ class CalendarController {
}
//
void addWeekChangeListener(OnWeekChange listener){
void addWeekChangeListener(OnWeekChange listener) {
this.calendarConfiguration.weekChangeListeners.add(listener);
}
@ -204,6 +206,11 @@ class CalendarController {
this.calendarConfiguration.calendarSelect = listener;
}
//
void addOnCalendarUnSelectListener(OnCalendarUnSelect listener) {
this.calendarConfiguration.unCalendarSelect = listener;
}
//
void addOnMultiSelectOutOfRangeListener(OnMultiSelectOutOfRange listener) {
this.calendarConfiguration.multiSelectOutOfRange = listener;
@ -506,8 +513,8 @@ class CalendarController {
monthList.clear();
weekList.clear();
calendarProvider.clearData();
calendarConfiguration.weekChangeListeners=null;
calendarConfiguration.monthChangeListeners=null;
calendarConfiguration.weekChangeListeners = null;
calendarConfiguration.monthChangeListeners = null;
}
}
@ -557,6 +564,10 @@ typedef void OnMonthChange(int year, int month);
*
*/
typedef void OnCalendarSelect(DateModel dateModel);
/**
*
*/
typedef void OnCalendarUnSelect(DateModel dateModel);
/**
*

@ -1,12 +1,17 @@
library flutter_custom_calendar;
export 'package:flutter_custom_calendar/controller.dart';
export 'package:flutter_custom_calendar/widget/calendar_view.dart';
export 'package:flutter_custom_calendar/widget/base_day_view.dart';
export 'package:flutter_custom_calendar/widget/base_week_bar.dart';
export 'package:flutter_custom_calendar/constants/constants.dart';
export 'package:flutter_custom_calendar/model/date_model.dart';
export 'package:flutter_custom_calendar/widget/default_combine_day_view.dart';
export 'package:flutter_custom_calendar/widget/default_custom_day_view.dart';
export 'package:flutter_custom_calendar/widget/default_week_bar.dart';
export 'package:flutter_custom_calendar/configuration.dart';
export 'controller.dart';
export 'widget/calendar_view.dart';
export 'widget/base_day_view.dart';
export 'widget/base_week_bar.dart';
export 'constants/constants.dart';
export 'model/date_model.dart';
export 'widget/default_combine_day_view.dart';
export 'widget/default_custom_day_view.dart';
export 'widget/default_week_bar.dart';
export 'configuration.dart';
export 'configuration.dart';
export 'calendar_provider.dart';
export 'constants/constants.dart';
export 'widget/base_day_view.dart';

@ -1,6 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'LogUtil.dart';
/**
*
@ -117,7 +117,8 @@ class DateUtil {
print('initCalendarForMonthView start');
weekStart = DateTime.monday;
//
int mPreDiff = getIndexOfFirstDayInMonth(new DateTime(year, month), offset: offset);
int mPreDiff =
getIndexOfFirstDayInMonth(new DateTime(year, month), offset: offset);
//
int monthDayCount = getMonthDaysCount(year, month);
@ -126,7 +127,6 @@ class DateUtil {
message:
"initCalendarForMonthView:$year$month月,有$monthDayCount天,第一天的index为${mPreDiff}");
List<DateModel> result = new List();
int size = 42;
@ -171,11 +171,11 @@ class DateUtil {
if (extraDataMap?.isNotEmpty == true) {
if (extraDataMap.containsKey(dateModel)) {
dateModel.extraData = extraDataMap[dateModel];
}else{
dateModel.extraData=null;
} else {
dateModel.extraData = null;
}
}else{
dateModel.extraData=null;
} else {
dateModel.extraData = null;
}
result.add(dateModel);
@ -197,8 +197,7 @@ class DateUtil {
int lineCount = ((preIndex + monthDayCount) / 7).ceil();
LogUtil.log(
TAG: "DateUtil",
message:
"getMonthViewLineCount:$year$month月:有$lineCount");
message: "getMonthViewLineCount:$year$month月:有$lineCount");
return lineCount;
}

@ -1,6 +1,4 @@
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/utils/solar_term_util.dart';
/**

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/controller.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import '../controller.dart';
/**
* canvasitem

@ -1,14 +1,17 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/controller.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:flutter_custom_calendar/widget/month_view_pager.dart';
import 'package:flutter_custom_calendar/widget/week_view_pager.dart';
import 'package:provider/provider.dart';
import '../calendar_provider.dart';
import '../controller.dart';
import 'month_view_pager.dart';
/**
*
*/
@ -167,7 +170,8 @@ class CalendarContainerState extends State<CalendarContainer>
.showMode !=
CalendarConstants.MODE_SHOW_ONLY_WEEK) {
//setState使
int lineCount = DateUtil.getMonthViewLineCount(year, month, widget.calendarController.calendarConfiguration.offset);
int lineCount = DateUtil.getMonthViewLineCount(year, month,
widget.calendarController.calendarConfiguration.offset);
double newHeight = itemHeight * (lineCount) +
calendarProvider.calendarConfiguration.verticalSpacing *
(lineCount - 1);

@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/widget/base_day_view.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/style/style.dart';
import 'base_day_view.dart';
/**
* widgetitem
*/

@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/widget/base_day_view.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/style/style.dart';
import 'base_day_view.dart';
/**
* StatelessWidgetstate
*/

@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/widget/base_week_bar.dart';
import 'package:flutter_custom_calendar/style/style.dart';
import 'base_week_bar.dart';
///**
// *
// */

@ -1,10 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/cache_data.dart';
import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:flutter_custom_calendar/configuration.dart';
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:provider/provider.dart';
@ -113,7 +111,7 @@ class _MonthViewState extends State<MonthView>
switch (configuration.selectMode) {
///
case CalendarConstants.MODE_MULTI_SELECT:
case CalendarSelectedMode.multiSelect:
if (calendarProvider.selectedDateList.contains(dateModel)) {
dateModel.isSelected = true;
} else {
@ -123,7 +121,7 @@ class _MonthViewState extends State<MonthView>
///
case CalendarConstants.MODE_MULTI_SELECT_FROM_TO_END:
case CalendarSelectedMode.mutltiStartToEndSelect:
if (calendarProvider.selectedDateList.contains(dateModel)) {
dateModel.isSelected = true;
} else {
@ -132,7 +130,7 @@ class _MonthViewState extends State<MonthView>
break;
///
case CalendarConstants.MODE_SINGLE_SELECT:
case CalendarSelectedMode.singleSelect:
if (calendarProvider.selectDateModel == dateModel) {
dateModel.isSelected = true;
} else {
@ -143,8 +141,15 @@ class _MonthViewState extends State<MonthView>
return ItemContainer(
dateModel: dateModel,
key: ObjectKey(
dateModel), //使objectKey1flutter2statefulElementstate
key: ObjectKey(dateModel),
clickCall: () {
setState(() {});
// if (configuration.selectMode ==
// CalendarSelectedMode.mutltiStartToEndSelect)
///
},
//使objectKey1flutter2statefulElementstate
);
});
}
@ -159,10 +164,9 @@ class _MonthViewState extends State<MonthView>
class ItemContainer extends StatefulWidget {
final DateModel dateModel;
const ItemContainer({
Key key,
this.dateModel,
}) : super(key: key);
final GestureTapCallback clickCall;
const ItemContainer({Key key, this.dateModel, this.clickCall})
: super(key: key);
@override
ItemContainerState createState() => ItemContainerState();
@ -180,14 +184,6 @@ class ItemContainerState extends State<ItemContainer> {
super.initState();
dateModel = widget.dateModel;
isSelected = ValueNotifier(dateModel.isSelected);
//
// WidgetsBinding.instance.addPostFrameCallback((callback) {
// if (configuration.selectMode == CalendarConstants.MODE_SINGLE_SELECT &&
// dateModel.isSelected) {
// calendarProvider.lastClickItemState = this;
// }
// });
}
/**
@ -199,12 +195,28 @@ class ItemContainerState extends State<ItemContainer> {
The following assertion was thrown while handling a gesture:
setState() called after dispose()
*/
v ??= false;
if (mounted) {
setState(() {
dateModel.isSelected = v;
// isSelected.value = !isSelected.value;
});
}
if (widget.clickCall != null) {
widget.clickCall();
}
}
void _notifiCationUnCalendarSelect(DateModel element) {
if (configuration.unCalendarSelect != null) {
configuration.unCalendarSelect(element);
}
}
void _notifiCationCalendarSelect(DateModel element) {
if (configuration.calendarSelect != null) {
configuration.calendarSelect(element);
}
}
@override
@ -224,7 +236,7 @@ class ItemContainerState extends State<ItemContainer> {
//
if (!dateModel.isInRange) {
//
if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) {
if (configuration.selectMode == CalendarSelectedMode.multiSelect) {
configuration.multiSelectOutOfRange();
}
return;
@ -234,7 +246,7 @@ class ItemContainerState extends State<ItemContainer> {
switch (configuration.selectMode) {
//
case CalendarConstants.MODE_MULTI_SELECT:
case CalendarSelectedMode.multiSelect:
if (calendarProvider.selectedDateList.contains(dateModel)) {
calendarProvider.selectedDateList.remove(dateModel);
} else {
@ -248,17 +260,21 @@ class ItemContainerState extends State<ItemContainer> {
}
calendarProvider.selectedDateList.add(dateModel);
}
if (configuration.calendarSelect != null) {
configuration.calendarSelect(dateModel);
}
//
calendarProvider.selectDateModel = dateModel;
break;
///
case CalendarConstants.MODE_SINGLE_SELECT:
calendarProvider.selectDateModel = dateModel;
case CalendarSelectedMode.singleSelect:
///
calendarProvider.selectedDateList.forEach((element) {
if (configuration.unCalendarSelect != null) {
configuration.unCalendarSelect(element);
}
element.isSelected = false;
});
if (configuration.calendarSelect != null) {
configuration.calendarSelect(dateModel);
}
@ -268,14 +284,28 @@ class ItemContainerState extends State<ItemContainer> {
calendarProvider.lastClickItemState?.refreshItem(false);
calendarProvider.lastClickItemState = this;
}
_notifiCationUnCalendarSelect(calendarProvider.selectDateModel);
calendarProvider.selectDateModel = dateModel;
setState(() {});
break;
///
case CalendarConstants.MODE_MULTI_SELECT_FROM_TO_END:
case CalendarSelectedMode.mutltiStartToEndSelect:
if (calendarProvider.selectedDateList.length == 0) {
calendarProvider.selectedDateList.add(dateModel);
} else if (calendarProvider.selectedDateList.length == 1) {
DateModel d2 = calendarProvider.selectedDateList.last;
DateModel d2 = calendarProvider.selectedDateList.first;
if (calendarProvider.selectedDateList.contains(dateModel)) {
///
dateModel.isSelected = false;
_notifiCationUnCalendarSelect(dateModel);
setState(() {});
return;
}
DateTime t1, t2;
if (d2.getDateTime().isAfter(dateModel.getDateTime())) {
t2 = d2.getDateTime();
@ -289,13 +319,24 @@ class ItemContainerState extends State<ItemContainer> {
.add(DateModel.fromDateTime(t1));
t1 = t1.add(Duration(days: 1));
}
calendarProvider.selectedDateList.add(DateModel.fromDateTime(t1));
} else {
///
calendarProvider.selectedDateList.forEach((element) {
element.isSelected = false;
_notifiCationUnCalendarSelect(element);
});
///
calendarProvider.selectedDateList.clear();
setState(() {});
}
if (configuration.calendarSelect != null) {
///
if (configuration.calendarSelect != null &&
calendarProvider.selectedDateList.length > 0) {
calendarProvider.selectedDateList.forEach((element) {
configuration.calendarSelect(element);
_notifiCationCalendarSelect(element);
});
}
break;

@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:flutter_custom_calendar/configuration.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/widget/month_view.dart';
import 'package:provider/provider.dart';
class MonthViewPager extends StatefulWidget {

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_custom_calendar/configuration.dart';
import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:flutter_custom_calendar/widget/month_view.dart';
import 'package:provider/provider.dart';

@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:flutter_custom_calendar/configuration.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/widget/week_view.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_custom_calendar/configuration.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart';
class WeekViewPager extends StatefulWidget {
const WeekViewPager({Key key}) : super(key: key);

@ -0,0 +1,9 @@
void main() {
// test('adds one to input values', () {
// final calculator = Calculator();
// expect(calculator.addOne(2), 3);
// expect(calculator.addOne(-7), -6);
// expect(calculator.addOne(0), 1);
// expect(() => calculator.addOne(null), throwsNoSuchMethodError);
// });
}
Loading…
Cancel
Save