fanguangyong 4 years ago
parent 0f86c621a0
commit a881182be2

@ -1,26 +1,2 @@
### 近期修改 ## [1.0.1]
- 新增多选范围功能
### [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,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'; controller = new CalendarController(
``` minYear: 2019,
3.创建CalendarViewWidget对象配置CalendarController
```
CalendarController controller= new CalendarController(
minYear: 2018,
minYearMonth: 1, minYearMonth: 1,
maxYear: 2020, maxYear: 2021,
maxYearMonth: 12, maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK); showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK,
CalendarViewWidget calendar= CalendarViewWidget( selectedDateTimeList: _selectedDate,
calendarController: controller, selectMode: CalendarSelectedMode.mutltiStartToEndSelect)
), ..addOnCalendarSelectListener((dateModel) {
``` _selectedModels.add(dateModel);
})
* boxDecoration用来配置整体的背景 ..addOnCalendarUnSelectListener((dateModel) {
* 利用CalendarController来配置一些数据并且可以通过CalendarController进行一些操作或者事件监听比如滚动到下一个月获取当前被选中的Item等等。 if (_selectedModels.contains(dateModel)) {
_selectedModels.remove(dateModel);
4.操作日历 }
``` });
controller.toggleExpandStatus();//月视图和周视图的切换
```
``` ```
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 ## Getting Started

@ -22,28 +22,22 @@ if (flutterVersionName == null) {
} }
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
compileSdkVersion 28 compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions { lintOptions {
disable 'InvalidPackage' disable 'InvalidPackage'
} }
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // 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 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 28
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@ -58,10 +52,3 @@ android {
flutter { flutter {
source '../..' 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" <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 <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <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 <!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method. calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide 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. --> FlutterApplication and put your custom class here. -->
<application <application
android:name="io.flutter.app.FlutterApplication" android:name="io.flutter.app.FlutterApplication"
android:label="example1" android:label="example"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
@ -16,17 +16,32 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing <!-- Specifies an Android theme to apply to this Activity as soon as
until Flutter renders its first frame. It can be removed if the Android process has started. This theme is visible to the user
there is no splash screen (such as the default splash screen while the Flutter UI initializes. After that, this theme continues
defined in @style/LaunchTheme). --> to determine the Window background behind the Flutter UI. -->
<meta-data <meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:name="io.flutter.embedding.android.NormalTheme"
android:value="true" /> 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> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </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> </application>
</manifest> </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"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Theme applied to the Android Window while the process is starting -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when <!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame --> Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowBackground">@drawable/launch_background</item>
</style> </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> </resources>

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

@ -1,5 +1,4 @@
buildscript { buildscript {
ext.kotlin_version = '1.3.50'
repositories { repositories {
google() google()
jcenter() jcenter()
@ -7,7 +6,6 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.0' 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; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1020; LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "The Chromium Authors"; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
@ -145,7 +145,7 @@
}; };
}; };
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 9.3";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
@ -308,7 +308,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example1; PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -442,7 +442,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example1; PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -469,7 +469,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example1; PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; 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> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>example1</string> <string>example</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>

@ -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 'package:flutter/cupertino.dart';
import 'red_style_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'blue_style_page.dart'; import 'package:flutter_custom_calendar/constants/constants.dart';
import 'custom_sign_page.dart'; import 'package:flutter_custom_calendar/controller.dart';
import 'custom_style_page.dart'; import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'default_style_page.dart';
import 'multi_select_style_page.dart';
import 'progress_style_page.dart';
void main() { void main() {
// debugProfileBuildsEnabled=true;
// debugProfilePaintsEnabled=true;
// debugPrintRebuildDirtyWidgets=true;
runApp(MyApp()); runApp(MyApp());
} }
@ -22,98 +15,162 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( 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', title: 'Flutter Demo',
theme: ThemeData( theme: ThemeData(
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
), visualDensity: VisualDensity.adaptivePlatformDensity,
home: HomePage()); 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 @override
Widget build(BuildContext context) { void initState() {
return new Scaffold( _selectedDate.add(DateTime.now());
body: SafeArea( controller = new CalendarController(
child: new Column( 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>[ children: <Widget>[
new RaisedButton( Text(
onPressed: () { model.day.toString(),
Navigator.pushNamed(context, "/default"); style: TextStyle(
}, color: model.isCurrentMonth
child: new Text("默认风格+单选"), ? (_isSelected == false
? (model.isWeekend
? Colors.black38
: Colors.black87)
: Colors.white)
: Colors.black38),
),
// Text(model.lunarDay.toString()),
],
), ),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/custom");
},
child: new Text("自定义风格+单选"),
), ),
new RaisedButton( );
onPressed: () {
Navigator.pushNamed(context, "/multi_select");
}, },
child: new Text("自定义风格+多选"), );
super.initState();
}
String _selectDate = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
), ),
new RaisedButton( body: Center(
onPressed: () { child: Column(
Navigator.pushNamed(context, "/progress"); mainAxisAlignment: MainAxisAlignment.center,
}, children: <Widget>[
child: new Text("进度条风格+单选"), Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.start,
children: <Widget>[
Text('请选择mode'),
FlatButton(
child: Text(
'singleSelect',
style: TextStyle(color: Colors.white),
), ),
new RaisedButton(
onPressed: () { onPressed: () {
Navigator.pushNamed(context, "/custom_sign"); setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.singleSelect;
});
}, },
child: new Text("自定义额外数据,实现标记功能"), color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.singleSelect
? Colors.teal
: Colors.black38,
), ),
new RaisedButton( FlatButton(
onPressed: () { child: Text(
Navigator.pushNamed(context, "/only_week_view"); 'multiSelect',
}, style: TextStyle(color: Colors.white),
child: new Text("仅显示周视图"),
), ),
new RaisedButton(
onPressed: () { onPressed: () {
Navigator.pushNamed(context, "/blue_style_page"); setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.multiSelect;
});
}, },
child: new Text("蓝色Demo"), color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.multiSelect
? Colors.teal
: Colors.black38,
), ),
new RaisedButton( FlatButton(
onPressed: () { child: Text(
Navigator.pushNamed(context, "/red_style_page"); 'mutltiStartToEndSelect',
}, style: TextStyle(color: Colors.white),
child: new Text("红色Demo"),
), ),
new RaisedButton(
onPressed: () { onPressed: () {
Navigator.pushNamed(context, "/custom_offset_page"); setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.mutltiStartToEndSelect;
});
}, },
child: new Text("自定义偏移量"), color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.mutltiStartToEndSelect
? Colors.teal
: Colors.black38,
)
],
),
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 name: cupertino_icons
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.2" version: "0.1.3"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -72,10 +72,10 @@ packages:
flutter_custom_calendar: flutter_custom_calendar:
dependency: "direct main" dependency: "direct main"
description: description:
path: ".." name: flutter_custom_calendar
relative: true url: "https://pub.flutter-io.cn"
source: path source: hosted
version: "0.0.1" version: "1.0.2"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -137,13 +137,6 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.3" 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: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter

@ -1,5 +1,9 @@
name: example1 name: example
description: A new Flutter project. 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. # The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43 # 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 version: 1.0.0+1
environment: environment:
sdk: ">=2.1.0 <3.0.0" sdk: ">=2.7.0 <3.0.0"
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2 cupertino_icons: ^0.1.3
random_pk: ^0.0.3 flutter_custom_calendar: ^1.0.2
flutter_custom_calendar:
path: ../
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec

@ -8,23 +8,21 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:example1/main.dart';
void main() { void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async { // testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame. // // Build our app and trigger a frame.
await tester.pumpWidget(MyApp()); // await tester.pumpWidget(MyApp());
//
// Verify that our counter starts at 0. // // Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget); // expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing); // expect(find.text('1'), findsNothing);
//
// Tap the '+' icon and trigger a frame. // // Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add)); // await tester.tap(find.byIcon(Icons.add));
await tester.pump(); // await tester.pump();
//
// Verify that our counter has incremented. // // Verify that our counter has incremented.
expect(find.text('0'), findsNothing); // expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget); // 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; static CacheData get instance => _instance;
Map<DateModel, List<DateModel>> monthListCache = Map(); Map<DateModel, List<DateModel>> monthListCache = Map();
Map<DateModel, List<DateModel>> weekListCache = Map(); Map<DateModel, List<DateModel>> weekListCache = Map();
static CacheData getInstance() { static CacheData getInstance() {
@ -21,14 +22,8 @@ class CacheData {
return _instance; return _instance;
} }
void clearData() {
void clearData(){
monthListCache.clear(); monthListCache.clear();
weekListCache.clear(); weekListCache.clear();
} }
} }

@ -2,13 +2,13 @@ import 'dart:collection';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/cache_data.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 '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 * provider
@ -173,7 +173,9 @@ class CalendarProvider extends ChangeNotifier {
calendarConfiguration.showMode == calendarConfiguration.showMode ==
CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) { CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) {
int lineCount = DateUtil.getMonthViewLineCount( int lineCount = DateUtil.getMonthViewLineCount(
calendarConfiguration.nowYear, calendarConfiguration.nowMonth, calendarConfiguration.offset); calendarConfiguration.nowYear,
calendarConfiguration.nowMonth,
calendarConfiguration.offset);
totalHeight = calendarConfiguration.itemSize * (lineCount) + totalHeight = calendarConfiguration.itemSize * (lineCount) +
calendarConfiguration.verticalSpacing * (lineCount - 1); calendarConfiguration.verticalSpacing * (lineCount - 1);
} else { } else {

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

@ -1,3 +1,5 @@
enum CalendarSelectedMode { singleSelect, multiSelect, mutltiStartToEndSelect }
class CalendarConstants { 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; // static const int MODE_SHOW_ONLY_MONTH = 1; //

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

@ -1,12 +1,17 @@
library flutter_custom_calendar; library flutter_custom_calendar;
export 'package:flutter_custom_calendar/controller.dart'; export 'controller.dart';
export 'package:flutter_custom_calendar/widget/calendar_view.dart'; export 'widget/calendar_view.dart';
export 'package:flutter_custom_calendar/widget/base_day_view.dart'; export 'widget/base_day_view.dart';
export 'package:flutter_custom_calendar/widget/base_week_bar.dart'; export 'widget/base_week_bar.dart';
export 'package:flutter_custom_calendar/constants/constants.dart'; export 'constants/constants.dart';
export 'package:flutter_custom_calendar/model/date_model.dart'; export 'model/date_model.dart';
export 'package:flutter_custom_calendar/widget/default_combine_day_view.dart'; export 'widget/default_combine_day_view.dart';
export 'package:flutter_custom_calendar/widget/default_custom_day_view.dart'; export 'widget/default_custom_day_view.dart';
export 'package:flutter_custom_calendar/widget/default_week_bar.dart'; export 'widget/default_week_bar.dart';
export 'package:flutter_custom_calendar/configuration.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/cupertino.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 'LogUtil.dart';
/** /**
* *
@ -117,7 +117,8 @@ class DateUtil {
print('initCalendarForMonthView start'); print('initCalendarForMonthView start');
weekStart = DateTime.monday; 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); int monthDayCount = getMonthDaysCount(year, month);
@ -126,7 +127,6 @@ class DateUtil {
message: message:
"initCalendarForMonthView:$year$month月,有$monthDayCount天,第一天的index为${mPreDiff}"); "initCalendarForMonthView:$year$month月,有$monthDayCount天,第一天的index为${mPreDiff}");
List<DateModel> result = new List(); List<DateModel> result = new List();
int size = 42; int size = 42;
@ -171,11 +171,11 @@ class DateUtil {
if (extraDataMap?.isNotEmpty == true) { if (extraDataMap?.isNotEmpty == true) {
if (extraDataMap.containsKey(dateModel)) { if (extraDataMap.containsKey(dateModel)) {
dateModel.extraData = extraDataMap[dateModel]; dateModel.extraData = extraDataMap[dateModel];
}else{ } else {
dateModel.extraData=null; dateModel.extraData = null;
} }
}else{ } else {
dateModel.extraData=null; dateModel.extraData = null;
} }
result.add(dateModel); result.add(dateModel);
@ -197,8 +197,7 @@ class DateUtil {
int lineCount = ((preIndex + monthDayCount) / 7).ceil(); int lineCount = ((preIndex + monthDayCount) / 7).ceil();
LogUtil.log( LogUtil.log(
TAG: "DateUtil", TAG: "DateUtil",
message: message: "getMonthViewLineCount:$year$month月:有$lineCount");
"getMonthViewLineCount:$year$month月:有$lineCount");
return lineCount; return lineCount;
} }

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

@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; 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/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import '../controller.dart';
/** /**
* canvasitem * canvasitem

@ -1,14 +1,17 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.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/constants/constants.dart';
import 'package:flutter_custom_calendar/controller.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart'; import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/utils/date_util.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:flutter_custom_calendar/widget/week_view_pager.dart';
import 'package:provider/provider.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 != .showMode !=
CalendarConstants.MODE_SHOW_ONLY_WEEK) { CalendarConstants.MODE_SHOW_ONLY_WEEK) {
//setState使 //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) + double newHeight = itemHeight * (lineCount) +
calendarProvider.calendarConfiguration.verticalSpacing * calendarProvider.calendarConfiguration.verticalSpacing *
(lineCount - 1); (lineCount - 1);

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

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

@ -1,8 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/constants/constants.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 'package:flutter_custom_calendar/style/style.dart';
import 'base_week_bar.dart';
///** ///**
// * // *
// */ // */

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

@ -1,9 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/calendar_provider.dart'; import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:flutter_custom_calendar/configuration.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/utils/LogUtil.dart';
import 'package:flutter_custom_calendar/widget/month_view.dart'; import 'package:flutter_custom_calendar/widget/month_view.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MonthViewPager extends StatefulWidget { class MonthViewPager extends StatefulWidget {

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; 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/configuration.dart';
import 'package:flutter_custom_calendar/constants/constants.dart'; import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart'; import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:flutter_custom_calendar/widget/month_view.dart'; import 'package:flutter_custom_calendar/widget/month_view.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; 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:flutter_custom_calendar/widget/week_view.dart';
import 'package:provider/provider.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 { class WeekViewPager extends StatefulWidget {
const WeekViewPager({Key key}) : super(key: key); 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