Compare commits

...

28 Commits

Author SHA1 Message Date
章文轩 3c60db6d87 农历节日优先级比公历节日优先显示
3 years ago
章文轩 2e9b7f62e2 provider版本升级适配萝卜丝客服
3 years ago
章文轩 c1b3c0c0a7 fix bug
3 years ago
章文轩 31de633004 fix null bug
3 years ago
章文轩 adb48f42d7 fix bug
3 years ago
章文轩 cc420e3b1f 降级provider
3 years ago
章文轩 e3b1e9aa76 fix bug
3 years ago
章文轩 4f50105cac null safe
3 years ago
小赖 b36def9c64 fix yaml
5 years ago
小赖 4ca8065cde 添加垂直方向滑动
5 years ago
ifgyong 0b98d4dda4 fix bug 2020.7.21
5 years ago
ifgyong fe5c7e4480 fix bug
5 years ago
ifgyong 5dccd93949 gif
5 years ago
ifgyong fe04f186db add
5 years ago
ifgyong e1e32ac48b a
5 years ago
fanguangyong a881182be2 a
5 years ago
fanguangyong 0f86c621a0 多选
5 years ago
LXD312569496 820b9e6477
Merge pull request #57 from msidolphin/patch-1
5 years ago
msidolphin 57b38bf60c
fix: 周视图遗漏了offset
5 years ago
LXD312569496 47fcb6c67b
Merge pull request #54 from msidolphin/feat/day_offset
5 years ago
msidolphin 366bcf719d feat: 支持设置首日偏移量
5 years ago
xiaodong 7d35ade7f7 [plcs#8888] 取整问题,打日志控制
5 years ago
xiaodong ba084e6e6a [plcs#8888] 单点触摸
5 years ago
xiaodong 19c6f910e7 Merge branch 'master' of https://github.com/LXD312569496/flutter_custom_calendar
5 years ago
xiaodong 9d095c16ee [plcs#8888] 单点触摸
5 years ago
LXD312569496 2ca1935bc1
Merge pull request #46 from zileyuan/master
5 years ago
zileyuan f55b502b66 update provider
5 years ago
zileyuan 59256033b6 修复单选模式下可以多选日期的问题
5 years ago

@ -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>

@ -21,11 +21,10 @@
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" /> <excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.pub" /> <excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/example/.android/Flutter/build/intermediates/flutter/debug/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/example/.android/Flutter/build/intermediates/library_assets/debug/packageDebugAssets/out/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" /> <excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/.pub" /> <excludeFolder url="file://$MODULE_DIR$/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/build" /> <excludeFolder url="file://$MODULE_DIR$/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
</content> </content>
<orderEntry type="jdk" jdkName="Android API 28 Platform" jdkType="Android SDK" /> <orderEntry type="jdk" jdkName="Android API 28 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />

@ -5,174 +5,198 @@
<entry key="async"> <entry key="async">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/async-2.1.0/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/async-2.6.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="boolean_selector"> <entry key="boolean_selector">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/boolean_selector-1.0.4/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" />
</list>
</value>
</entry>
<entry key="characters">
<value>
<list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="charcode"> <entry key="charcode">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/charcode-1.1.2/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib" />
</list>
</value>
</entry>
<entry key="clock">
<value>
<list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="collection"> <entry key="collection">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/collection-1.14.11/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="cupertino_icons"> <entry key="cupertino_icons">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/cupertino_icons-0.1.2/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/cupertino_icons-0.1.3/lib" />
</list>
</value>
</entry>
<entry key="fake_async">
<value>
<list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/fake_async-1.2.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter"> <entry key="flutter">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter/lib" /> <option value="/Applications/sdk/flutter/packages/flutter/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_test"> <entry key="flutter_test">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter_test/lib" /> <option value="/Applications/sdk/flutter/packages/flutter_test/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="matcher"> <entry key="matcher">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/matcher-0.12.5/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/matcher-0.12.10/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="meta"> <entry key="meta">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/meta-1.1.6/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/meta-1.3.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path"> <entry key="nested">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/path-1.6.2/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="pedantic"> <entry key="path">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/pedantic-1.5.0/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="quiver"> <entry key="provider">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/quiver-2.0.2/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/provider-6.0.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="sky_engine"> <entry key="sky_engine">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/pkg/sky_engine/lib" /> <option value="/Applications/sdk/flutter/bin/cache/pkg/sky_engine/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="source_span"> <entry key="source_span">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/source_span-1.5.5/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/source_span-1.8.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="stack_trace"> <entry key="stack_trace">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/stack_trace-1.9.3/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="stream_channel"> <entry key="stream_channel">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/stream_channel-2.0.0/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="string_scanner"> <entry key="string_scanner">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/string_scanner-1.0.4/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="term_glyph"> <entry key="term_glyph">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/term_glyph-1.1.0/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="test_api"> <entry key="test_api">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/test_api-0.2.4/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/test_api-0.3.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="typed_data"> <entry key="typed_data">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/typed_data-1.1.6/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="vector_math"> <entry key="vector_math">
<value> <value>
<list> <list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/vector_math-2.0.8/lib" /> <option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
</option> </option>
</properties> </properties>
<CLASSES> <CLASSES>
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/async-2.1.0/lib" /> <root url="file:///Applications/sdk/flutter/bin/cache/pkg/sky_engine/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/boolean_selector-1.0.4/lib" /> <root url="file:///Applications/sdk/flutter/packages/flutter/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/charcode-1.1.2/lib" /> <root url="file:///Applications/sdk/flutter/packages/flutter_test/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/collection-1.14.11/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/async-2.6.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/cupertino_icons-0.1.2/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/matcher-0.12.5/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/meta-1.1.6/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/path-1.6.2/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/pedantic-1.5.0/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/quiver-2.0.2/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/cupertino_icons-0.1.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/source_span-1.5.5/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/fake_async-1.2.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/stack_trace-1.9.3/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/matcher-0.12.10/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/stream_channel-2.0.0/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/meta-1.3.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/string_scanner-1.0.4/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/term_glyph-1.1.0/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/test_api-0.2.4/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/provider-6.0.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/typed_data-1.1.6/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/source_span-1.8.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/vector_math-2.0.8/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/pkg/sky_engine/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter_test/lib" /> <root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib" />
<root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/test_api-0.3.0/lib" />
<root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib" />
<root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.0/lib" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -1,26 +1,26 @@
<component name="libraryTable"> <component name="libraryTable">
<library name="Dart SDK"> <library name="Dart SDK">
<CLASSES> <CLASSES>
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/async" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/async" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/cli" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/cli" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/collection" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/convert" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/core" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/core" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/developer" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/ffi" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/ffi" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/html" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/html" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/indexed_db" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/indexed_db" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/io" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/io" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/isolate" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/isolate" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/js" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/js" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/js_util" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/js_util" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/math" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/math" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/mirrors" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/svg" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/svg" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/typed_data" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/typed_data" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/web_audio" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/web_audio" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/web_gl" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/web_gl" />
<root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/web_sql" /> <root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/web_sql" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -1,172 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="AndroidLayouts">
<shared>
<config />
</shared>
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="18463f0e-cf10-4ee2-975b-376476396e12" name="Default Changelist" comment=""> <list default="true" id="18463f0e-cf10-4ee2-975b-376476396e12" name="Default Changelist" comment="Default Changelist">
<change afterPath="$PROJECT_DIR$/.idea/markdown-navigator.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/markdown-navigator/profiles_settings.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/flutter_custom_calendar.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/flutter_custom_calendar.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" /> <change beforePath="$PROJECT_DIR$/lib/model/date_model.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/model/date_model.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/base_day_view.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/base_day_view.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/base_week_bar.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/base_week_bar.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/calendar_view.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/calendar_view.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/controller.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/controller.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/default_combine_day_view.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/default_combine_day_view.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/default_custom_day_view.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/default_custom_day_view.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/default_week_bar.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/default_week_bar.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/flutter_custom_calendar.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_custom_calendar.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/month_view.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/month_view.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/month_view_pager.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/month_view_pager.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/week_view.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/widget/week_view.dart" afterDir="false" />
</list> </list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" /> <option name="LAST_RESOLUTION" value="IGNORE" />
</component> </component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SPLIT">
<first_editor relative-caret-position="1123">
<caret line="78" column="6" selection-start-line="78" selection-start-column="6" selection-end-line="78" selection-end-column="6" />
</first_editor>
<second_editor>
<markdownNavigatorState />
</second_editor>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SPLIT">
<first_editor />
<second_editor>
<markdownNavigatorState />
</second_editor>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/flutter_custom_calendar.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
<caret line="2" column="50" selection-start-line="2" selection-start-column="50" selection-end-line="2" selection-end-column="50" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/controller.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="147">
<caret line="60" selection-start-line="60" selection-end-line="79" selection-end-column="55" />
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/widget/base_day_view.dart">
<provider selected="true" editor-type-id="text-editor">
<state>
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/widget/base_week_bar.dart">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
</leaf>
</component>
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component> </component>
<component name="IdeDocumentHistory"> <component name="ProjectId" id="1dLYXgUqXFRhtM2vVF7WEPgjPS2" />
<option name="CHANGED_PATHS"> <component name="ProjectReloadState">
<list> <option name="STATE" value="1" />
<option value="$PROJECT_DIR$/example/lib/progress_style_page.dart" />
<option value="$PROJECT_DIR$/example/lib/custom_style_page.dart" />
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
<option value="$PROJECT_DIR$/example/lib/main.dart" />
<option value="$PROJECT_DIR$/lib/flutter_custom_calendar.dart" />
<option value="$PROJECT_DIR$/example/lib/default_style_page.dart" />
<option value="$PROJECT_DIR$/example/lib/multi_select_style_page.dart" />
<option value="$PROJECT_DIR$/lib/widget/calendar_view.dart" />
<option value="$PROJECT_DIR$/lib/widget/default_week_bar.dart" />
<option value="$PROJECT_DIR$/lib/widget/month_view.dart" />
<option value="$PROJECT_DIR$/lib/widget/month_view_pager.dart" />
<option value="$PROJECT_DIR$/README.md" />
</list>
</option>
</component>
<component name="ProjectFrameBounds">
<option name="y" value="23" />
<option name="width" value="1440" />
<option name="height" value="806" />
</component> </component>
<component name="ProjectView"> <component name="ProjectViewState">
<navigator currentView="ProjectPane" proportions="" version="1"> <option name="hideEmptyMiddlePackages" value="true" />
<foldersAlwaysOnTop value="true" /> <option name="showLibraryContents" value="true" />
</navigator>
<panes>
<pane id="Scope" />
<pane id="AndroidView" />
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="flutter_custom_calendar" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_custom_calendar" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_custom_calendar" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_custom_calendar" type="462c0819:PsiDirectoryNode" />
<item name="example" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_custom_calendar" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_custom_calendar" type="462c0819:PsiDirectoryNode" />
<item name="example" type="462c0819:PsiDirectoryNode" />
<item name="lib" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_custom_calendar" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_custom_calendar" type="462c0819:PsiDirectoryNode" />
<item name="lib" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_custom_calendar" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_custom_calendar" type="462c0819:PsiDirectoryNode" />
<item name="lib" type="462c0819:PsiDirectoryNode" />
<item name="widget" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="PackagesPane" />
</panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="android.sdk.path" value="$USER_HOME$/Library/Android/sdk" /> <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="android.sdk.path" value="$PROJECT_DIR$/../Library/Android/sdk" />
<property name="dart.analysis.tool.window.force.activate" value="false" /> <property name="dart.analysis.tool.window.force.activate" value="false" />
<property name="dart.analysis.tool.window.visible" value="false" />
<property name="io.flutter.reload.alreadyRun" value="true" /> <property name="io.flutter.reload.alreadyRun" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" /> <property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="preferences.pluginManager" /> <property name="settings.editor.selected.configurable" value="flutter.settings" />
<property name="show.migrate.to.gradle.popup" value="false" /> <property name="show.migrate.to.gradle.popup" value="false" />
</component> </component>
<component name="RecentsManager"> <component name="RecentsManager">
@ -177,18 +49,6 @@
<recent name="$PROJECT_DIR$/example/lib" /> <recent name="$PROJECT_DIR$/example/lib" />
</key> </key>
</component> </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" selected="Flutter.main.dart"> <component name="RunManager" selected="Flutter.main.dart">
<configuration name="main.dart (1)" type="FlutterRunConfigurationType" factoryName="Flutter" singleton="false" temporary="true" nameIsGenerated="true"> <configuration name="main.dart (1)" type="FlutterRunConfigurationType" factoryName="Flutter" singleton="false" temporary="true" nameIsGenerated="true">
<option name="filePath" value="$PROJECT_DIR$/lib/demo_page/main.dart" /> <option name="filePath" value="$PROJECT_DIR$/lib/demo_page/main.dart" />
@ -204,6 +64,7 @@
</list> </list>
</recent_temporary> </recent_temporary>
</component> </component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="SvnConfiguration"> <component name="SvnConfiguration">
<configuration /> <configuration />
</component> </component>
@ -217,209 +78,16 @@
</task> </task>
<servers /> <servers />
</component> </component>
<component name="ToolWindowManager"> <component name="Vcs.Log.Tabs.Properties">
<frame x="0" y="23" width="1440" height="806" extended-state="0" /> <option name="TAB_STATES">
<editor active="true" /> <map>
<layout> <entry key="MAIN">
<window_info id="Captures" order="0" side_tool="true" weight="0.25" /> <value>
<window_info active="true" content_ui="combo" id="Project" order="1" visible="true" weight="0.3040057" /> <State />
<window_info id="Structure" order="2" side_tool="true" /> </value>
<window_info id="Image Layers" order="3" /> </entry>
<window_info id="Designer" order="4" /> </map>
<window_info id="Resources Explorer" order="5" /> </option>
<window_info id="Capture Tool" order="6" /> <option name="oldMeFiltersMigrated" value="true" />
<window_info id="Favorites" order="7" side_tool="true" />
<window_info id="Build Variants" order="8" side_tool="true" />
<window_info anchor="bottom" id="Run" order="0" sideWeight="0.49928468" weight="0.32913166" />
<window_info anchor="bottom" id="TODO" order="1" />
<window_info anchor="bottom" id="Debug" order="2" />
<window_info anchor="bottom" id="Terminal" order="3" weight="0.32913166" />
<window_info anchor="bottom" id="Event Log" order="4" sideWeight="0.50143063" side_tool="true" weight="0.32913166" />
<window_info anchor="bottom" id="Flutter Performance" order="5" side_tool="true" />
<window_info anchor="bottom" id="Version Control" order="6" />
<window_info anchor="bottom" id="Dart Analysis" order="7" weight="0.32913166" />
<window_info anchor="bottom" id="Messages" order="8" sideWeight="0.49928468" weight="0.32913166" />
<window_info anchor="bottom" id="Logcat" order="9" />
<window_info anchor="bottom" id="Android Profiler" order="10" show_stripe_button="false" />
<window_info anchor="right" id="Capture Analysis" order="0" />
<window_info anchor="right" id="Theme Preview" order="1" />
<window_info anchor="right" id="Flutter Inspector" order="2" />
<window_info anchor="right" id="Flutter Outline" order="3" />
<window_info anchor="right" id="Palette&#9;" order="4" />
<window_info anchor="right" id="Device File Explorer" order="5" side_tool="true" />
</layout>
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
<caret line="9" column="11" selection-start-line="9" selection-start-column="11" selection-end-line="9" selection-end-column="11" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="235">
<caret line="31" column="13" selection-start-line="31" selection-start-column="13" selection-end-line="31" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/custom_style_page.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="70" selection-start-line="1" selection-end-line="2" />
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/multi_select_style_page.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="1" selection-start-line="10" selection-start-column="1" selection-end-line="10" selection-end-column="1" />
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/progress_style_page.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="39" selection-start-line="1" selection-start-column="16" selection-end-line="1" selection-end-column="39" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="12" column="14" selection-start-line="12" selection-start-column="14" selection-end-line="12" selection-end-column="14" />
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/default_style_page.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="44" selection-start-line="1" selection-end-line="2" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/calendar_view.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="238">
<caret line="15" column="13" lean-forward="true" selection-start-line="15" selection-start-column="13" selection-end-line="15" selection-end-column="13" />
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/default_combine_day_view.dart">
<provider selected="true" editor-type-id="text-editor">
<state>
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/default_custom_day_view.dart">
<provider selected="true" editor-type-id="text-editor">
<state>
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/default_week_bar.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="485">
<caret line="49" column="12" selection-start-line="49" selection-start-column="12" selection-end-line="49" selection-end-column="12" />
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/base_day_view.dart">
<provider selected="true" editor-type-id="text-editor">
<state>
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/base_week_bar.dart">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/month_view.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="51">
<caret line="3" selection-start-line="3" selection-end-line="3" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/month_view_pager.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
<caret line="2" selection-start-line="2" selection-end-line="2" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/widget/week_view.dart">
<provider selected="true" editor-type-id="text-editor">
<state>
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/flutter_custom_calendar.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
<caret line="2" column="50" selection-start-line="2" selection-start-column="50" selection-end-line="2" selection-end-column="50" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/controller.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="147">
<caret line="60" selection-start-line="60" selection-end-line="79" selection-end-column="55" />
<folding>
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SPLIT">
<first_editor relative-caret-position="1123">
<caret line="78" column="6" selection-start-line="78" selection-start-column="6" selection-end-line="78" selection-end-column="6" />
</first_editor>
<second_editor>
<markdownNavigatorState />
</second_editor>
</state>
</provider>
<provider editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SPLIT">
<first_editor />
<second_editor>
<markdownNavigatorState />
</second_editor>
</state>
</provider>
</entry>
</component> </component>
</project> </project>

@ -74,7 +74,8 @@
Set<DateTime> selectedDateTimeList = EMPTY_SET, Set<DateTime> selectedDateTimeList = EMPTY_SET,
DateModel selectDateModel, DateModel selectDateModel,
int maxMultiSelectCount = 9999, int maxMultiSelectCount = 9999,
Map<DateModel, Object> extraDataMap = EMPTY_MAP}) Map<DateModel, Object> extraDataMap = EMPTY_MAP,
int offset = 0})
``` ```
#### 通用参数说明 #### 通用参数说明
@ -94,11 +95,12 @@
| minSelectDay | 可以选择的最小月份的日子 | 1 | | minSelectDay | 可以选择的最小月份的日子 | 1 |
| maxSelectYear | 可以选择的最大年份 | 2055 | | maxSelectYear | 可以选择的最大年份 | 2055 |
| maxSelectMonth | 可以选择的最大年份的月份 | 12 | | maxSelectMonth | 可以选择的最大年份的月份 | 12 |
| maxSelectDay | 可以选择的最大月份的日子 | 30注意不能超过对应月份的总天数 | | maxSelectDay | 可以选择的最大月份的日子 | 30注意不能超过对应月份的总天数 |
| selectedDateList | 被选中的日期,用于多选 | 默认为空Set, Set<DateModel> selectedDateList = new Set() | | selectedDateList | 被选中的日期,用于多选 | 默认为空Set, Set<DateModel> selectedDateList = new Set() |
| selectDateModel | 当前选择项,用于单选 | 默认为空 | | selectDateModel | 当前选择项,用于单选 | 默认为空 |
| maxMultiSelectCount | 多选,最多选多少个 | hhh | | maxMultiSelectCount | 多选,最多选多少个 | hhh |
| extraDataMap | 自定义额外的数据 | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() | | extraDataMap | 自定义额外的数据 | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() |
| offset | 首日偏移量 | 0 |
#### 给controller添加事件监听 #### 给controller添加事件监听

@ -73,7 +73,8 @@ One is to use the controller to add event monitoring and use the controller to o
Set<DateTime> selectedDateTimeList = EMPTY_SET, Set<DateTime> selectedDateTimeList = EMPTY_SET,
DateModel selectDateModel, DateModel selectDateModel,
int maxMultiSelectCount = 9999, int maxMultiSelectCount = 9999,
Map<DateModel, Object> extraDataMap = EMPTY_MAP}) Map<DateModel, Object> extraDataMap = EMPTY_MAP,
int offset})
``` ```
#### General parameter description #### General parameter description
@ -98,6 +99,7 @@ One is to use the controller to add event monitoring and use the controller to o
| selectDateModel | Current selection, for radio selection | 默认为空 | | selectDateModel | Current selection, for radio selection | 默认为空 |
| maxMultiSelectCount | Multiple choice, how many at most | hhh | | maxMultiSelectCount | Multiple choice, how many at most | hhh |
| extraDataMap | Customize additional data | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() | | extraDataMap | Customize additional data | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() |
| offset | The offset of first day | 0 |
#### Add event listening to controller #### Add event listening to controller

@ -1,26 +1,5 @@
### 近期修改 ## [1.0.4+0.4]
- 新增三个模式相互且含数据不影响
## [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,90 @@
## 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上的一个日历控件可以定制成自己想要的样子。
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库 新增一个选择`mode`
```
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart'; 支持选择开始和结束,选择范围内的日期,使用方法
```
3.创建CalendarViewWidget对象配置CalendarController
``` ```
CalendarController controller= new CalendarController( controller = new CalendarController(
minYear: 2018, minYear: 2019,
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);
})
..addOnCalendarUnSelectListener((dateModel) {
if (_selectedModels.contains(dateModel)) {
_selectedModels.remove(dateModel);
}
});
``` ```
`CalendarSelectedMode.mutltiStartToEndSelect`这个选择模式会选择开始和结束中间的 默认选择的。
* boxDecoration用来配置整体的背景
* 利用CalendarController来配置一些数据并且可以通过CalendarController进行一些操作或者事件监听比如滚动到下一个月获取当前被选中的Item等等。
4.操作日历 ### 安装和使用
```
controller.toggleExpandStatus();//月视图和周视图的切换
```
``` Use this package as a library
controller.previousPage();//操作日历切换到上一页 1. Depend on it
``` Add this to your package's pubspec.yaml file:
``` ```
controller.nextPage();//操作日历切换到下一页 dependencies:
flutter_custom_calendar: ^1.0.4+0.5
``` ```
2. Install it
You can install packages from the command line:
## 2.0版本 with Flutter:
主要改动:
* UI配置相关的参数移动到CalendarView的构造方法里面旧版本是在controller里面配置
* 日历支持padding和margin属性item的大小计算修改
* 实现日历整体自适应高度
* controller提供changeExtraDataMap的方法可以随时动态的修改自定义数据extraDataMap
* 支持显示月视图和周视图的情况优先显示周视图MODE_SHOW_WEEK_AND_MONTH
* 支持verticalSpacing和itemSize属性
```
$ flutter pub get
```
## 注意事项 Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.
* 如果使用2.0之前的版本则需要将UI配置相关的参数移动到CalendarView的构造方法里面旧版本是在controller里面配置 3. Import it
* 暂时没有发现其他问题,如果有其他问题,可以跟我说一下。 Now in your Dart code, you can use:
* 如果你用这个库做了日历,可以将展示结果分享给我,我贴到文档上进行展示
```
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
```
### 监听月视图和周视图状态
```dart WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
controller.addExpandChangeListener((value) {
/// 添加改变 月视图和 周视图的监听
_isMonthSelected = value;
setState(() {});
});
});
```
### 变更月视图和周视图
> 前提条件是`showModel`是`CalendarConstants.MODE_SHOW_MONTH_AND_WEEK`或者`CalendarConstants.MODE_SHOW_WEEK_AND_MONTH`.
#### 变更到周视图
```dart
setState(() {
controller.weekAndMonthViewChange(CalendarConstants.MODE_SHOW_ONLY_WEEK);
});
```
## 主要API文档 #### 变更到月视图
```dart
setState(() {controller.weekAndMonthViewChange(CalendarConstants.MODE_SHOW_ONLY_MONTH);
});
```
[API Documentation](API.md) ### 动画演示
![](img.gif)
### [查看API](https://github.com/ifgyong/flutter_custom_calendar/blob/master/API.md)
### [查看一个例子 如何使用](https://github.com/ifgyong/flutter_custom_calendar/blob/master/example/lib/main.dart)

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>

@ -9,11 +9,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@ -26,8 +22,6 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
); );
name = "Embed Frameworks"; name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -38,13 +32,11 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@ -57,8 +49,6 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -68,9 +58,7 @@
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */, 9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */,
@ -148,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;
@ -157,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 = (
@ -201,7 +189,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
}; };
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
@ -320,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;
@ -454,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";
@ -481,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,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,17 +1,12 @@
import 'only_week_page.dart'; import 'dart:collection';
import 'red_style_page.dart';
import 'package:flutter/cupertino.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());
} }
@ -20,95 +15,244 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
// checkerboardOffscreenLayers: true, // 使saveLayer title: 'Flutter Demo',
routes: <String, WidgetBuilder>{ theme: ThemeData(
"/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"),
},
title: 'Flutter Demo',
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();
GlobalKey<CalendarContainerState> _globalKey = new GlobalKey();
@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,
children: <Widget>[ minYearMonth: 1,
new RaisedButton( maxYear: 2021,
onPressed: () { maxYearMonth: 12,
Navigator.pushNamed(context, "/default"); showMode: CalendarConstants.MODE_SHOW_WEEK_AND_MONTH,
}, selectedDateTimeList: _selectedDate,
child: new Text("默认风格+单选"), selectMode: CalendarSelectedMode.singleSelect)
), ..addOnCalendarSelectListener((dateModel) {
new RaisedButton( _selectedModels.add(dateModel);
onPressed: () { setState(() {
Navigator.pushNamed(context, "/custom"); _selectDate = _selectedModels.toString();
}, });
child: new Text("自定义风格+单选"), })
..addOnCalendarUnSelectListener((dateModel) {
if (_selectedModels.contains(dateModel)) {
_selectedModels.remove(dateModel);
}
setState(() {
_selectDate = '';
});
});
calendar = new CalendarViewWidget(
key: _globalKey,
calendarController: controller,
dayWidgetBuilder: (DateModel model) {
double wd = (MediaQuery.of(context).size.width - 20) / 7;
bool _isSelected = model.isSelected;
if (_isSelected &&
CalendarSelectedMode.singleSelect ==
controller.calendarConfiguration.selectMode) {
_selectDate = model.toString();
}
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(wd / 2)),
child: Container(
color: _isSelected ? Theme.of(context).focusColor : Colors.white,
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
model.day.toString(),
style: TextStyle(
color: model.isCurrentMonth
? (_isSelected == false
? (model.isWeekend
? Colors.black38
: Colors.black87)
: Colors.white)
: Colors.black38),
),
// Text(model.lunarDay.toString()),
],
), ),
new RaisedButton( ),
onPressed: () { );
Navigator.pushNamed(context, "/multi_select"); },
}, );
child: new Text("自定义风格+多选"), WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
), controller.addExpandChangeListener((value) {
new RaisedButton( ///
onPressed: () { _isMonthSelected = value;
Navigator.pushNamed(context, "/progress"); setState(() {});
}, });
child: new Text("进度条风格+单选"), });
),
new RaisedButton( super.initState();
onPressed: () { }
Navigator.pushNamed(context, "/custom_sign");
}, bool _isMonthSelected = false;
child: new Text("自定义额外数据,实现标记功能"),
), String _selectDate = '';
new RaisedButton( @override
onPressed: () { Widget build(BuildContext context) {
Navigator.pushNamed(context, "/only_week_view"); return Scaffold(
}, appBar: AppBar(
child: new Text("仅显示周视图"), title: Text(widget.title),
), ),
new RaisedButton( body: CupertinoScrollbar(
onPressed: () { child: CustomScrollView(
Navigator.pushNamed(context, "/blue_style_page"); slivers: <Widget>[
}, _topButtons(),
child: new Text("蓝色Demo"), _topMonths(),
SliverToBoxAdapter(
child: calendar,
), ),
new RaisedButton( SliverToBoxAdapter(
onPressed: () { child: Container(
Navigator.pushNamed(context, "/red_style_page"); child: Text(
}, ' $_selectDate ',
child: new Text("红色Demo"), style: TextStyle(color: Theme.of(context).focusColor),
),
),
) )
], ],
), ),
), ),
); );
} }
Widget _topButtons() {
return SliverToBoxAdapter(
child: Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.start,
children: <Widget>[
Text('请选择mode'),
Wrap(
spacing: 10,
runSpacing: 10,
children: <Widget>[
FlatButton(
child: Text(
'单选',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.singleSelect;
});
},
color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.singleSelect
? Colors.teal
: Colors.black38,
),
FlatButton(
child: Text(
'多选',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.multiSelect;
});
},
color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.multiSelect
? Colors.teal
: Colors.black38,
),
FlatButton(
child: Text(
'多选 选择开始和结束',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.calendarConfiguration.selectMode =
CalendarSelectedMode.mutltiStartToEndSelect;
});
},
color: controller.calendarConfiguration.selectMode ==
CalendarSelectedMode.mutltiStartToEndSelect
? Colors.teal
: Colors.black38,
),
],
),
],
),
);
}
Widget _topMonths() {
return SliverToBoxAdapter(
child: Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.start,
children: <Widget>[
Text('月视图和周视图'),
Wrap(
spacing: 10,
runSpacing: 10,
children: <Widget>[
FlatButton(
child: Text(
'月视图',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.weekAndMonthViewChange(
CalendarConstants.MODE_SHOW_ONLY_WEEK);
});
},
color: _isMonthSelected ? Colors.teal : Colors.black38,
),
FlatButton(
child: Text(
'周视图',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
controller.weekAndMonthViewChange(
CalendarConstants.MODE_SHOW_ONLY_MONTH);
});
},
color: _isMonthSelected == false ? Colors.teal : Colors.black38,
),
],
),
],
),
);
}
} }

@ -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),
),
),
),
],
),
],
),
);
}
}

@ -1,69 +1,62 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
archive:
dependency: transitive
description:
name: archive
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.10"
args:
dependency: transitive
description:
name: args
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.5.2"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.3.0" version: "2.6.1"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "2.1.0"
charcode: characters:
dependency: transitive dependency: transitive
description: description:
name: charcode name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.2" version: "1.1.0"
collection: charcode:
dependency: transitive dependency: transitive
description: description:
name: collection name: charcode
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.11" version: "1.2.0"
convert: clock:
dependency: transitive dependency: transitive
description: description:
name: convert name: clock
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "1.1.0"
crypto: collection:
dependency: transitive dependency: transitive
description: description:
name: crypto name: collection
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.3" version: "1.15.0"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
name: cupertino_icons name: cupertino_icons
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2" version: "0.1.3"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -75,75 +68,47 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.0.1" version: "1.0.4+0.5"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
image:
dependency: transitive
description:
name: image
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.5" version: "0.12.10"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted
version: "1.1.7"
path:
dependency: transitive
description:
name: path
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.6.4" version: "1.3.0"
pedantic: nested:
dependency: transitive dependency: transitive
description: description:
name: pedantic name: nested
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0+1" version: "1.0.0"
petitparser: path:
dependency: transitive dependency: transitive
description: description:
name: petitparser name: path
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.0" version: "1.8.0"
provider: provider:
dependency: transitive dependency: transitive
description: description:
name: provider name: provider
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0+1"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.5"
random_pk:
dependency: "direct main"
description:
name: random_pk
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.0.3" version: "6.0.3"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -153,64 +118,58 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.5" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.3" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.1.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.5" version: "0.3.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.6" version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.5.0" version: "2.1.0"
sdks: sdks:
dart: ">=2.4.0 <3.0.0" dart: ">=2.12.0 <3.0.0"
flutter: ">=1.16.0"

@ -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,24 @@ 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: flutter_custom_calendar:
path: ../ 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
@ -44,8 +49,8 @@ flutter:
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: # assets:
# - images/a_dot_burr.jpeg # - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware. # https://flutter.dev/assets-and-images/#resolution-aware.

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

@ -1,4 +1,4 @@
import 'package:flutter_custom_calendar/model/date_model.dart'; import 'model/date_model.dart';
/** /**
* *
@ -7,28 +7,23 @@ class CacheData {
// //
CacheData._(); CacheData._();
static CacheData _instance; static CacheData? _instance;
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() {
if (_instance == null) { if (_instance == null) {
_instance = new CacheData._(); _instance = new 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
@ -16,13 +16,13 @@ import 'package:flutter_custom_calendar/widget/month_view.dart';
* rebuild * rebuild
*/ */
class CalendarProvider extends ChangeNotifier { class CalendarProvider extends ChangeNotifier {
double _totalHeight; // double? _totalHeight; //
HashSet<DateModel> selectedDateList = new HashSet<DateModel>(); //, HashSet<DateModel?>? selectedDateList = new HashSet<DateModel?>(); //,
DateModel _selectDateModel; // DateModel? _selectDateModel; //
ItemContainerState lastClickItemState; ItemContainerState? lastClickItemState;
DateModel _lastClickDateModel; DateModel? _lastClickDateModel;
double get totalHeight => _totalHeight; double? get totalHeight => _totalHeight;
ValueNotifier<int> _generation = ValueNotifier<int> _generation =
new ValueNotifier(0); //int new ValueNotifier(0); //int
@ -33,7 +33,7 @@ class CalendarProvider extends ChangeNotifier {
_generation = value; _generation = value;
} }
set totalHeight(double value) { set totalHeight(double? value) {
_totalHeight = value; _totalHeight = value;
} }
@ -42,17 +42,17 @@ class CalendarProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
DateModel get lastClickDateModel => DateModel? get lastClickDateModel =>
_lastClickDateModel; // _lastClickDateModel; //
set lastClickDateModel(DateModel value) { set lastClickDateModel(DateModel? value) {
_lastClickDateModel = value; _lastClickDateModel = value;
print("lastClickDateModel:$lastClickDateModel"); print("lastClickDateModel:$lastClickDateModel");
} }
DateModel get selectDateModel => _selectDateModel; DateModel? get selectDateModel => _selectDateModel;
set selectDateModel(DateModel value) { set selectDateModel(DateModel? value) {
_selectDateModel = value; _selectDateModel = value;
LogUtil.log( LogUtil.log(
TAG: this.runtimeType, TAG: this.runtimeType,
@ -63,12 +63,12 @@ class CalendarProvider extends ChangeNotifier {
//lastClickDateModelindex //lastClickDateModelindex
int get weekPageIndex { int get weekPageIndex {
//index //index
DateModel dateModel = lastClickDateModel; DateModel? dateModel = lastClickDateModel;
DateTime firstWeek = calendarConfiguration.weekList[0].getDateTime(); DateTime firstWeek = calendarConfiguration!.weekList![0].getDateTime();
int index = 0; int index = 0;
for (int i = 0; i < calendarConfiguration.weekList.length; i++) { for (int i = 0; i < calendarConfiguration!.weekList!.length; i++) {
DateTime nextWeek = firstWeek.add(Duration(days: 7)); DateTime nextWeek = firstWeek.add(Duration(days: 7));
if (dateModel.getDateTime().isBefore(nextWeek)) { if (dateModel!.getDateTime().isBefore(nextWeek)) {
index = i; index = i;
break; break;
} else { } else {
@ -84,12 +84,12 @@ class CalendarProvider extends ChangeNotifier {
//lastClickDateModelindex //lastClickDateModelindex
int get monthPageIndex { int get monthPageIndex {
//index //index
DateModel dateModel = lastClickDateModel; DateModel? dateModel = lastClickDateModel;
int index = 0; int index = 0;
for (int i = 0; i < calendarConfiguration.monthList.length - 1; i++) { for (int i = 0; i < calendarConfiguration!.monthList!.length - 1; i++) {
DateTime preMonth = calendarConfiguration.monthList[i].getDateTime(); DateTime preMonth = calendarConfiguration!.monthList![i].getDateTime();
DateTime nextMonth = calendarConfiguration.monthList[i + 1].getDateTime(); DateTime nextMonth = calendarConfiguration!.monthList![i + 1].getDateTime();
if (!dateModel.getDateTime().isBefore(preMonth) && if (!dateModel!.getDateTime().isBefore(preMonth) &&
!dateModel.getDateTime().isAfter(nextMonth)) { !dateModel.getDateTime().isAfter(nextMonth)) {
index = i; index = i;
break; break;
@ -102,36 +102,37 @@ class CalendarProvider extends ChangeNotifier {
return index + 1; return index + 1;
} }
ValueNotifier<bool> expandStatus; // late ValueNotifier<bool> expandStatus; //
// //
CalendarConfiguration calendarConfiguration; CalendarConfiguration? calendarConfiguration;
void weekAndMonthViewChange(int mode) {}
void initData({ void initData({
Set<DateModel> selectedDateList, Set<DateModel>? selectedDateList,
DateModel selectDateModel, DateModel? selectDateModel,
CalendarConfiguration calendarConfiguration, required CalendarConfiguration calendarConfiguration,
EdgeInsetsGeometry padding, EdgeInsetsGeometry? padding,
EdgeInsetsGeometry margin, EdgeInsetsGeometry? margin,
double itemSize, double? itemSize,
double verticalSpacing, double? verticalSpacing,
DayWidgetBuilder dayWidgetBuilder, DayWidgetBuilder? dayWidgetBuilder,
WeekBarItemWidgetBuilder weekBarItemWidgetBuilder, WeekBarItemWidgetBuilder? weekBarItemWidgetBuilder,
}) { }) {
LogUtil.log(TAG: this.runtimeType, message: "CalendarProvider initData"); LogUtil.log(TAG: this.runtimeType, message: "CalendarProvider initData");
this.calendarConfiguration = calendarConfiguration; this.calendarConfiguration = calendarConfiguration;
print( print(
"calendarConfiguration.defaultSelectedDateList:${calendarConfiguration.defaultSelectedDateList}"); "calendarConfiguration.defaultSelectedDateList:${calendarConfiguration.defaultSelectedDateList}");
this this
.selectedDateList .selectedDateList!
.addAll(this.calendarConfiguration.defaultSelectedDateList); .addAll(this.calendarConfiguration!.defaultSelectedDateList!);
this.selectDateModel = this.calendarConfiguration.selectDateModel; this.selectDateModel = this.calendarConfiguration!.selectDateModel;
this.calendarConfiguration.padding = padding; this.calendarConfiguration!.padding = padding;
this.calendarConfiguration.margin = margin; this.calendarConfiguration!.margin = margin;
this.calendarConfiguration.itemSize = itemSize; this.calendarConfiguration!.itemSize = itemSize;
this.calendarConfiguration.verticalSpacing = verticalSpacing; this.calendarConfiguration!.verticalSpacing = verticalSpacing;
this.calendarConfiguration.dayWidgetBuilder = dayWidgetBuilder; this.calendarConfiguration!.dayWidgetBuilder = dayWidgetBuilder;
this.calendarConfiguration.weekBarItemWidgetBuilder = this.calendarConfiguration!.weekBarItemWidgetBuilder =
weekBarItemWidgetBuilder; weekBarItemWidgetBuilder;
//lastClickDateModelitem //lastClickDateModelitem
@ -151,16 +152,16 @@ class CalendarProvider extends ChangeNotifier {
//itemitemSize/7/7paddingmargin //itemitemSize/7/7paddingmargin
if (calendarConfiguration.itemSize == null) { if (calendarConfiguration.itemSize == null) {
MediaQueryData mediaQueryData = MediaQueryData mediaQueryData =
MediaQueryData.fromWindow(WidgetsBinding.instance.window); MediaQueryData.fromWindow(WidgetsBinding.instance!.window);
if (mediaQueryData.orientation == Orientation.landscape) { if (mediaQueryData.orientation == Orientation.landscape) {
calendarConfiguration.itemSize = (mediaQueryData.size.height - calendarConfiguration.itemSize = (mediaQueryData.size.height -
calendarConfiguration.padding.vertical - calendarConfiguration.padding!.vertical -
calendarConfiguration.margin.vertical) / calendarConfiguration.margin!.vertical) /
7; 7;
} else { } else {
calendarConfiguration.itemSize = (mediaQueryData.size.width - calendarConfiguration.itemSize = (mediaQueryData.size.width -
calendarConfiguration.padding.horizontal - calendarConfiguration.padding!.horizontal -
calendarConfiguration.margin.horizontal) / calendarConfiguration.margin!.horizontal) /
7; 7;
} }
} else { } else {
@ -173,9 +174,11 @@ 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.nowYear!,
totalHeight = calendarConfiguration.itemSize * (lineCount) + calendarConfiguration.nowMonth!,
calendarConfiguration.verticalSpacing * (lineCount - 1); calendarConfiguration.offset);
totalHeight = calendarConfiguration.itemSize! * (lineCount) +
calendarConfiguration.verticalSpacing! * (lineCount - 1);
} else { } else {
totalHeight = calendarConfiguration.itemSize; totalHeight = calendarConfiguration.itemSize;
} }
@ -184,8 +187,8 @@ class CalendarProvider extends ChangeNotifier {
//退 //退
void clearData() { void clearData() {
LogUtil.log(TAG: this.runtimeType, message: "CalendarProvider clearData"); LogUtil.log(TAG: this.runtimeType, message: "CalendarProvider clearData");
CacheData.getInstance().clearData(); CacheData.getInstance()!.clearData();
selectedDateList.clear(); selectedDateList!.clear();
selectDateModel = null; selectDateModel = null;
calendarConfiguration = null; calendarConfiguration = null;
} }

@ -1,82 +1,90 @@
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;
// //
int minYear; int? minYear;
int maxYear; int? maxYear;
// //
int minYearMonth; int? minYearMonth;
int maxYearMonth; int? maxYearMonth;
// //
int nowYear; int? nowYear;
int nowMonth; int? nowMonth;
//, //,
int minSelectYear; int? minSelectYear;
int minSelectMonth; int? minSelectMonth;
int minSelectDay; int? minSelectDay;
int maxSelectYear; int? maxSelectYear;
int maxSelectMonth; int? maxSelectMonth;
int maxSelectDay; // int? maxSelectDay; //
DateModel selectDateModel; //item DateModel? selectDateModel; //item
HashSet<DateModel> defaultSelectedDateList; //set HashSet<DateModel?>? defaultSelectedDateList; //set
int maxMultiSelectCount; // int? maxMultiSelectCount; //
Map<DateModel, Object> extraDataMap = new Map(); // Map<DateModel, Object>? extraDataMap = new Map(); //
/** /**
* UI * UI
*/ */
double itemSize; ///7 double? itemSize; ///7
double verticalSpacing; //item10 double? verticalSpacing; //item10
BoxDecoration boxDecoration; // BoxDecoration? boxDecoration; //
EdgeInsetsGeometry padding; EdgeInsetsGeometry? padding;
EdgeInsetsGeometry margin; EdgeInsetsGeometry? margin;
// //
DayWidgetBuilder dayWidgetBuilder; //item DayWidgetBuilder? dayWidgetBuilder; //item
WeekBarItemWidgetBuilder weekBarItemWidgetBuilder; //weekbar WeekBarItemWidgetBuilder? weekBarItemWidgetBuilder; //weekbar
/** /**
* *
*/ */
// //
OnMonthChange monthChange; // ,multiMonthChanges OnMonthChange? monthChange; // ,multiMonthChanges
OnCalendarSelect calendarSelect; // OnCalendarSelect? calendarSelect; //
OnMultiSelectOutOfRange multiSelectOutOfRange; // OnCalendarSelect? unCalendarSelect; //
OnMultiSelectOutOfSize multiSelectOutOfSize; // late OnMultiSelectOutOfRange multiSelectOutOfRange; //
OnMultiSelectOutOfSize? multiSelectOutOfSize; //
ObserverList<OnMonthChange> monthChangeListeners = ObserverList<OnMonthChange>? monthChangeListeners =
ObserverList<OnMonthChange>(); // ObserverList<OnMonthChange>(); //
ObserverList<OnWeekChange> weekChangeListeners = ObserverList<OnWeekChange>? weekChangeListeners =
ObserverList<OnWeekChange>(); // ObserverList<OnWeekChange>(); //
/** /**
* *
*/ */
List<DateModel> monthList = new List(); //list List<DateModel>? monthList = []; //list
List<DateModel> weekList = new List(); //list List<DateModel>? weekList = [] ; //list
PageController monthController; //controller PageController? monthController; //controller
PageController weekController; //controller PageController? weekController; //controller
DateModel minSelectDate; DateModel? minSelectDate;
DateModel maxSelectDate; DateModel? maxSelectDate;
/// first day offset
/// first day = (first day of month or week) + offset
final int offset;
CalendarConfiguration( CalendarConfiguration(
{this.selectMode, {this.selectMode,
@ -104,7 +112,8 @@ class CalendarConfiguration {
this.itemSize, this.itemSize,
this.showMode, this.showMode,
this.padding, this.padding,
this.margin}); this.margin,
this.offset = 0});
@override @override
String toString() { String toString() {

@ -1,15 +1,23 @@
class CalendarConstants { enum CalendarSelectedMode { singleSelect, multiSelect, mutltiStartToEndSelect }
class CalendarConstants {
// //
//
static const int MODE_SINGLE_SELECT = 1; static const int MODE_SINGLE_SELECT = 1;
///
static const int MODE_MULTI_SELECT = 2; static const int MODE_MULTI_SELECT = 2;
// ///
static const int MODE_SHOW_ONLY_MONTH=1;//
static const int MODE_SHOW_ONLY_WEEK=2;// static const int MODE_MULTI_SELECT_START_TO_END = 3;
static const int MODE_SHOW_WEEK_AND_MONTH=3;//
static const int MODE_SHOW_MONTH_AND_WEEK=4;//
//
static const int MODE_SHOW_ONLY_MONTH = 1; //
static const int MODE_SHOW_ONLY_WEEK = 2; //
static const int MODE_SHOW_WEEK_AND_MONTH = 3; //
static const int MODE_SHOW_MONTH_AND_WEEK = 4; //
/** /**
* *

@ -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
@ -20,27 +22,27 @@ class CalendarController {
static const Map<DateModel, Object> EMPTY_MAP = {}; static const Map<DateModel, Object> EMPTY_MAP = {};
static const Duration DEFAULT_DURATION = const Duration(milliseconds: 500); static const Duration DEFAULT_DURATION = const Duration(milliseconds: 500);
CalendarConfiguration calendarConfiguration; late CalendarConfiguration calendarConfiguration;
CalendarProvider calendarProvider = CalendarProvider(); CalendarProvider calendarProvider = CalendarProvider();
/** /**
* *
*/ */
List<DateModel> monthList = new List(); //list List<DateModel> monthList = []; //list
List<DateModel> weekList = new List(); //list List<DateModel> weekList = []; //list
PageController monthController; //controller PageController? monthController; //controller
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,
int minYearMonth = 1, int minYearMonth = 1,
int maxYearMonth = 12, int maxYearMonth = 12,
int nowYear, int? nowYear,
int nowMonth, int? nowMonth,
int minSelectYear = 1971, int minSelectYear = 1971,
int minSelectMonth = 1, int minSelectMonth = 1,
int minSelectDay = 1, int minSelectDay = 1,
@ -48,9 +50,12 @@ class CalendarController {
int maxSelectMonth = 12, int maxSelectMonth = 12,
int maxSelectDay = 30, int maxSelectDay = 30,
Set<DateTime> selectedDateTimeList = EMPTY_SET, //item Set<DateTime> selectedDateTimeList = EMPTY_SET, //item
DateModel selectDateModel, //item DateModel? selectDateModel, //item
int maxMultiSelectCount = 9999, int maxMultiSelectCount = 9999,
Map<DateModel, Object> extraDataMap = EMPTY_MAP}) { Map<DateModel, Object> extraDataMap = EMPTY_MAP,
int offset = 0 //
}) {
assert(offset >= 0 && offset <= 6);
LogUtil.log(TAG: this.runtimeType, message: "init CalendarConfiguration"); LogUtil.log(TAG: this.runtimeType, message: "init CalendarConfiguration");
// //
if (nowYear == null) { if (nowYear == null) {
@ -76,10 +81,11 @@ class CalendarController {
extraDataMap: extraDataMap, extraDataMap: extraDataMap,
maxSelectDay: maxSelectDay, maxSelectDay: maxSelectDay,
maxMultiSelectCount: maxMultiSelectCount, maxMultiSelectCount: maxMultiSelectCount,
selectDateModel: selectDateModel); selectDateModel: selectDateModel,
offset: offset);
calendarConfiguration.defaultSelectedDateList = new HashSet<DateModel>(); calendarConfiguration.defaultSelectedDateList = new HashSet<DateModel?>();
calendarConfiguration.defaultSelectedDateList calendarConfiguration.defaultSelectedDateList!
.addAll(selectedDateTimeList.map((dateTime) { .addAll(selectedDateTimeList.map((dateTime) {
return DateModel.fromDateTime(dateTime); return DateModel.fromDateTime(dateTime);
}).toSet()); }).toSet());
@ -88,13 +94,13 @@ class CalendarController {
calendarProvider.selectedDateList = calendarProvider.selectedDateList =
calendarConfiguration.defaultSelectedDateList; calendarConfiguration.defaultSelectedDateList;
calendarConfiguration.minSelectDate = DateModel.fromDateTime(DateTime( calendarConfiguration.minSelectDate = DateModel.fromDateTime(DateTime(
calendarConfiguration.minSelectYear, calendarConfiguration.minSelectYear!,
calendarConfiguration.minSelectMonth, calendarConfiguration.minSelectMonth!,
calendarConfiguration.minSelectDay)); calendarConfiguration.minSelectDay!));
calendarConfiguration.maxSelectDate = DateModel.fromDateTime(DateTime( calendarConfiguration.maxSelectDate = DateModel.fromDateTime(DateTime(
calendarConfiguration.maxSelectYear, calendarConfiguration.maxSelectYear!,
calendarConfiguration.maxSelectMonth, calendarConfiguration.maxSelectMonth!,
calendarConfiguration.maxSelectDay)); calendarConfiguration.maxSelectDay!));
LogUtil.log( LogUtil.log(
TAG: this.runtimeType, TAG: this.runtimeType,
@ -105,18 +111,29 @@ class CalendarController {
maxYear, maxYear,
maxYearMonth, maxYearMonth,
))}"); ))}");
_weekAndMonthViewChange(showMode);
}
void _weekAndMonthViewChange(
int showMode,
) {
int? minYear = calendarConfiguration.minYear;
int? maxYear = calendarConfiguration.maxYear;
int? minYearMonth = calendarConfiguration.minYearMonth;
int? maxYearMonth = calendarConfiguration.maxYearMonth;
int? nowYear = calendarConfiguration.nowYear;
int? nowMonth = calendarConfiguration.nowMonth;
if (showMode != CalendarConstants.MODE_SHOW_ONLY_WEEK) { if (showMode != CalendarConstants.MODE_SHOW_ONLY_WEEK) {
//pageController,initialPage //pageController,initialPage
int initialPage = 0; int initialPage = 0;
int nowMonthIndex = 0; int nowMonthIndex = 0;
monthList.clear(); monthList.clear();
for (int i = minYear; i <= maxYear; i++) { for (int i = minYear!; i <= maxYear!; i++) {
for (int j = 1; j <= 12; j++) { for (int j = 1; j <= 12; j++) {
if (i == minYear && j < minYearMonth) { if (i == minYear && j < minYearMonth!) {
continue; continue;
} }
if (i == maxYear && j > maxYearMonth) { if (i == maxYear && j > maxYearMonth!) {
continue; continue;
} }
DateModel dateModel = new DateModel(); DateModel dateModel = new DateModel();
@ -149,13 +166,13 @@ class CalendarController {
nowYear = DateTime.now().year; nowYear = DateTime.now().year;
nowMonth = DateTime.now().month; nowMonth = DateTime.now().month;
} }
DateTime nowTime = new DateTime(nowYear, nowMonth, 15); DateTime nowTime = new DateTime(nowYear!, nowMonth!, 15);
DateTime firstDayOfMonth = DateTime(minYear, minYearMonth, 1); DateTime firstDayOfMonth = DateTime(minYear!, minYearMonth!, 1);
// //
DateTime firstWeekDate = DateTime firstWeekDate =
firstDayOfMonth.add(Duration(days: -(firstDayOfMonth.weekday - 1))); firstDayOfMonth.add(Duration(days: -(firstDayOfMonth.weekday - 1)));
DateTime lastDay = DateTime(maxYear, maxYearMonth, DateTime lastDay = DateTime(maxYear!, maxYearMonth!,
DateUtil.getMonthDaysCount(maxYear, maxYearMonth)); DateUtil.getMonthDaysCount(maxYear, maxYearMonth));
int temp = -1; int temp = -1;
for (DateTime dateTime = firstWeekDate; for (DateTime dateTime = firstWeekDate;
@ -177,22 +194,29 @@ class CalendarController {
"初始化星期视图的信息:一共有${weekList.length}个星期initialPage为$initialWeekPage"); "初始化星期视图的信息:一共有${weekList.length}个星期initialPage为$initialWeekPage");
this.weekController = new PageController(initialPage: initialWeekPage); this.weekController = new PageController(initialPage: initialWeekPage);
} }
calendarConfiguration.monthList = monthList; calendarConfiguration.monthList = monthList;
calendarConfiguration.weekList = weekList; calendarConfiguration.weekList = weekList;
calendarConfiguration.monthController = monthController; calendarConfiguration.monthController = monthController;
calendarConfiguration.weekController = weekController; calendarConfiguration.weekController = weekController;
calendarProvider.weekAndMonthViewChange(showMode);
}
void weekAndMonthViewChange(
int showMode,
) {
calendarProvider.expandStatus.value =
showMode == CalendarConstants.MODE_SHOW_ONLY_WEEK ? true : false;
} }
// //
void addWeekChangeListener(OnWeekChange listener){ void addWeekChangeListener(OnWeekChange listener) {
this.calendarConfiguration.weekChangeListeners.add(listener); this.calendarConfiguration.weekChangeListeners!.add(listener);
} }
// //
void addMonthChangeListener(OnMonthChange listener) { void addMonthChangeListener(OnMonthChange listener) {
// this.calendarConfiguration.monthChange = listener; // this.calendarConfiguration.monthChange = listener;
this.calendarConfiguration.monthChangeListeners.add(listener); this.calendarConfiguration.monthChangeListeners!.add(listener);
} }
// //
@ -200,6 +224,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;
@ -234,7 +263,7 @@ class CalendarController {
//item //item
void changeDefaultSelectedDateList(Set<DateModel> defaultSelectedDateList) { void changeDefaultSelectedDateList(Set<DateModel> defaultSelectedDateList) {
this.calendarConfiguration.defaultSelectedDateList = this.calendarConfiguration.defaultSelectedDateList =
defaultSelectedDateList; defaultSelectedDateList as HashSet<DateModel?>?;
this.calendarProvider.generation.value++; this.calendarProvider.generation.value++;
} }
@ -251,13 +280,13 @@ class CalendarController {
if (calendarProvider.expandStatus.value == true) { if (calendarProvider.expandStatus.value == true) {
// //
int currentIndex = int currentIndex =
calendarProvider.calendarConfiguration.monthController.page.toInt(); calendarProvider.calendarConfiguration!.monthController!.page!.toInt();
if (currentIndex == 0) { if (currentIndex == 0) {
return false; return false;
} else { } else {
calendarProvider.calendarConfiguration.monthController calendarProvider.calendarConfiguration!.monthController!
.previousPage(duration: DEFAULT_DURATION, curve: Curves.ease); .previousPage(duration: DEFAULT_DURATION, curve: Curves.ease);
calendarProvider.calendarConfiguration.monthChangeListeners calendarProvider.calendarConfiguration!.monthChangeListeners!
.forEach((listener) { .forEach((listener) {
listener(monthList[currentIndex - 1].year, listener(monthList[currentIndex - 1].year,
monthList[currentIndex - 1].month); monthList[currentIndex - 1].month);
@ -272,11 +301,11 @@ class CalendarController {
} else { } else {
// //
int currentIndex = int currentIndex =
calendarProvider.calendarConfiguration.weekController.page.toInt(); calendarProvider.calendarConfiguration!.weekController!.page!.toInt();
if (currentIndex == 0) { if (currentIndex == 0) {
return false; return false;
} else { } else {
calendarProvider.calendarConfiguration.weekController calendarProvider.calendarConfiguration!.weekController!
.previousPage(duration: DEFAULT_DURATION, curve: Curves.ease); .previousPage(duration: DEFAULT_DURATION, curve: Curves.ease);
return true; return true;
} }
@ -292,13 +321,13 @@ class CalendarController {
if (calendarProvider.expandStatus.value == true) { if (calendarProvider.expandStatus.value == true) {
// //
int currentIndex = int currentIndex =
calendarProvider.calendarConfiguration.monthController.page.toInt(); calendarProvider.calendarConfiguration!.monthController!.page!.toInt();
if (monthList.length - 1 == currentIndex) { if (monthList.length - 1 == currentIndex) {
return false; return false;
} else { } else {
calendarProvider.calendarConfiguration.monthController calendarProvider.calendarConfiguration!.monthController!
.nextPage(duration: DEFAULT_DURATION, curve: Curves.ease); .nextPage(duration: DEFAULT_DURATION, curve: Curves.ease);
calendarProvider.calendarConfiguration.monthChangeListeners calendarProvider.calendarConfiguration!.monthChangeListeners!
.forEach((listener) { .forEach((listener) {
listener(monthList[currentIndex + 1].year, listener(monthList[currentIndex + 1].year,
monthList[currentIndex + 1].month); monthList[currentIndex + 1].month);
@ -314,11 +343,11 @@ class CalendarController {
} else { } else {
// //
int currentIndex = int currentIndex =
calendarProvider.calendarConfiguration.weekController.page.toInt(); calendarProvider.calendarConfiguration!.weekController!.page!.toInt();
if (weekList.length - 1 == currentIndex) { if (weekList.length - 1 == currentIndex) {
return false; return false;
} else { } else {
calendarProvider.calendarConfiguration.weekController calendarProvider.calendarConfiguration!.weekController!
.nextPage(duration: DEFAULT_DURATION, curve: Curves.ease); .nextPage(duration: DEFAULT_DURATION, curve: Curves.ease);
return true; return true;
} }
@ -337,15 +366,15 @@ class CalendarController {
if (targetPage == -1) { if (targetPage == -1) {
return; return;
} }
if (calendarProvider.calendarConfiguration.monthController.hasClients == if (calendarProvider.calendarConfiguration!.monthController!.hasClients ==
false) { false) {
return; return;
} }
if (needAnimation) { if (needAnimation) {
calendarProvider.calendarConfiguration.monthController calendarProvider.calendarConfiguration!.monthController!
.animateToPage(targetPage, duration: duration, curve: curve); .animateToPage(targetPage, duration: duration, curve: curve);
} else { } else {
calendarProvider.calendarConfiguration.monthController calendarProvider.calendarConfiguration!.monthController!
.jumpToPage(targetPage); .jumpToPage(targetPage);
} }
} else { } else {
@ -360,15 +389,15 @@ class CalendarController {
return; return;
} }
} }
if (calendarProvider.calendarConfiguration.weekController.hasClients == if (calendarProvider.calendarConfiguration!.weekController!.hasClients ==
false) { false) {
return; return;
} }
if (needAnimation) { if (needAnimation) {
calendarProvider.calendarConfiguration.weekController calendarProvider.calendarConfiguration!.weekController!
.animateToPage(targetPage, duration: duration, curve: curve); .animateToPage(targetPage, duration: duration, curve: curve);
} else { } else {
calendarProvider.calendarConfiguration.weekController calendarProvider.calendarConfiguration!.weekController!
.jumpToPage(targetPage); .jumpToPage(targetPage);
} }
} }
@ -380,7 +409,7 @@ class CalendarController {
Duration duration = const Duration(milliseconds: 500), Duration duration = const Duration(milliseconds: 500),
Curve curve = Curves.ease}) { Curve curve = Curves.ease}) {
DateTime targetDateTime = monthList[calendarProvider DateTime targetDateTime = monthList[calendarProvider
.calendarConfiguration.monthController.page .calendarConfiguration!.monthController!.page!
.toInt() + .toInt() +
12] 12]
.getDateTime(); .getDateTime();
@ -395,7 +424,7 @@ class CalendarController {
Duration duration = const Duration(milliseconds: 500), Duration duration = const Duration(milliseconds: 500),
Curve curve = Curves.ease}) { Curve curve = Curves.ease}) {
DateTime targetDateTime = monthList[calendarProvider DateTime targetDateTime = monthList[calendarProvider
.calendarConfiguration.monthController.page .calendarConfiguration!.monthController!.page!
.toInt() - .toInt() -
12] 12]
.getDateTime(); .getDateTime();
@ -411,30 +440,30 @@ class CalendarController {
Curve curve = Curves.ease}) { Curve curve = Curves.ease}) {
// indexweekController // indexweekController
if (calendarProvider.expandStatus.value == false) { if (calendarProvider.expandStatus.value == false) {
int currentMonth = weekList[calendarProvider int? currentMonth = weekList[calendarProvider
.calendarConfiguration.weekController.page .calendarConfiguration!.weekController!.page!
.toInt()] .toInt()]
.month; .month;
for (int i = calendarProvider.calendarConfiguration.weekController.page for (int i = calendarProvider.calendarConfiguration!.weekController!.page!
.toInt(); .toInt();
i < weekList.length; i < weekList.length;
i++) { i++) {
if (weekList[i].month != currentMonth) { if (weekList[i].month != currentMonth) {
calendarProvider.calendarConfiguration.weekController.jumpToPage(i); calendarProvider.calendarConfiguration!.weekController!.jumpToPage(i);
break; break;
} }
} }
return; return;
} }
if ((calendarProvider.calendarConfiguration.monthController.page.toInt() + if ((calendarProvider.calendarConfiguration!.monthController!.page!.toInt() +
1) >= 1) >=
monthList.length) { monthList.length) {
LogUtil.log(TAG: this.runtimeType, message: "moveToNextMonth当前是最后一个月份"); LogUtil.log(TAG: this.runtimeType, message: "moveToNextMonth当前是最后一个月份");
return; return;
} }
DateTime targetDateTime = monthList[calendarProvider DateTime targetDateTime = monthList[calendarProvider
.calendarConfiguration.monthController.page .calendarConfiguration!.monthController!.page!
.toInt() + .toInt() +
1] 1]
.getDateTime(); .getDateTime();
@ -450,30 +479,30 @@ class CalendarController {
Curve curve = Curves.ease}) { Curve curve = Curves.ease}) {
// indexweekController // indexweekController
if (calendarProvider.expandStatus.value == false) { if (calendarProvider.expandStatus.value == false) {
int currentMonth = weekList[weekController.page.toInt()].month; int? currentMonth = weekList[weekController!.page!.toInt()].month;
for (int i = calendarProvider.calendarConfiguration.weekController.page for (int i = calendarProvider.calendarConfiguration!.weekController!.page!
.toInt(); .toInt();
i >= 0; i >= 0;
i--) { i--) {
if (weekList[i].month != currentMonth && if (weekList[i].month != currentMonth &&
weekList[i].isAfter(DateModel.fromDateTime(DateTime( weekList[i].isAfter(DateModel.fromDateTime(DateTime(
calendarConfiguration.minYear, calendarConfiguration.minYear!,
calendarConfiguration.minYearMonth)))) { calendarConfiguration.minYearMonth!)))) {
calendarProvider.calendarConfiguration.weekController.jumpToPage(i); calendarProvider.calendarConfiguration!.weekController!.jumpToPage(i);
break; break;
} }
} }
return; return;
} }
if ((calendarProvider.calendarConfiguration.monthController.page.toInt()) == if ((calendarProvider.calendarConfiguration!.monthController!.page!.toInt()) ==
0) { 0) {
LogUtil.log( LogUtil.log(
TAG: this.runtimeType, message: "moveToPreviousMonth当前是第一个月份"); TAG: this.runtimeType, message: "moveToPreviousMonth当前是第一个月份");
return; return;
} }
DateTime targetDateTime = monthList[calendarProvider DateTime targetDateTime = monthList[calendarProvider
.calendarConfiguration.monthController.page .calendarConfiguration!.monthController!.page!
.toInt() - .toInt() -
1] 1]
.getDateTime(); .getDateTime();
@ -484,16 +513,16 @@ class CalendarController {
// //
DateModel getCurrentMonth() { DateModel getCurrentMonth() {
return monthList[monthController.page.toInt()]; return monthList[monthController!.page!.toInt()];
} }
//, //,
Set<DateModel> getMultiSelectCalendar() { Set<DateModel?>? getMultiSelectCalendar() {
return calendarProvider.selectedDateList; return calendarProvider.selectedDateList;
} }
// //
DateModel getSingleSelectCalendar() { DateModel? getSingleSelectCalendar() {
return calendarProvider.selectDateModel; return calendarProvider.selectDateModel;
} }
@ -502,8 +531,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;
} }
} }
@ -542,17 +571,21 @@ bool defaultInRange(DateModel dateModel) {
/** /**
* *
*/ */
typedef void OnWeekChange(int year, int month); typedef void OnWeekChange(int? year, int? month);
/** /**
* *
*/ */
typedef void OnMonthChange(int year, int month); 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';

@ -5,11 +5,11 @@ import 'package:flutter_custom_calendar/utils/lunar_util.dart';
* *
*/ */
class DateModel { class DateModel {
int year; int? year;
int month; int? month;
int day = 1; int day = 1;
List<int> lunar = List(3); List<int> lunar = [];
// List<int> get lunar { // List<int> get lunar {
// if (lunar?.isNotEmpty == false) { // if (lunar?.isNotEmpty == false) {
@ -22,53 +22,53 @@ class DateModel {
String get lunarString { String get lunarString {
if (solarTerm.isNotEmpty) { if (solarTerm.isNotEmpty) {
return solarTerm; return solarTerm;
} else if (gregorianFestival.isNotEmpty) {
return gregorianFestival;
} else if (traditionFestival.isNotEmpty) { } else if (traditionFestival.isNotEmpty) {
return traditionFestival; return traditionFestival;
} else if (gregorianFestival.isNotEmpty) {
return gregorianFestival;
} else { } else {
return LunarUtil.numToChinese(lunar[1], lunar[2], lunar[3]); return LunarUtil.numToChinese(lunar[1], lunar[2], lunar[3]);
} }
} }
//24 //24
String get solarTerm => LunarUtil.getSolarTerm(year, month, day); String get solarTerm => LunarUtil.getSolarTerm(year, month!, day);
// //
String get gregorianFestival { String get gregorianFestival {
String result = LunarUtil.gregorianFestival(month, day); String result = LunarUtil.gregorianFestival(month!, day);
if (result?.isNotEmpty == true) { if (result.isNotEmpty == true) {
return result; return result;
} }
return LunarUtil.getSpecialFestival(year, month, day); return LunarUtil.getSpecialFestival(year, month!, day);
} }
// //
String get traditionFestival => String get traditionFestival =>
LunarUtil.getTraditionFestival(lunarYear, lunarMonth, lunarDay); LunarUtil.getTraditionFestival(lunarYear, lunarMonth, lunarDay);
bool isCurrentMonth; // bool? isCurrentMonth; //
Object extraData; // Object? extraData; //
bool isInRange = false; //, bool isInRange = false; //,
bool isSelected; // bool? isSelected; //
bool isCanClick = bool isCanClick =
true; //todo:truefalse true; //todo:truefalse
// //
bool get isWeekend => DateUtil.isWeekend(getDateTime()); bool get isWeekend => DateUtil.isWeekend(getDateTime());
// //
bool get isLeapYear => DateUtil.isLeapYear(year); bool get isLeapYear => DateUtil.isLeapYear(year!);
// //
bool get isCurrentDay => DateUtil.isCurrentDay(year, month, day); bool get isCurrentDay => DateUtil.isCurrentDay(year, month, day);
int get lunarYear => lunar[0]; int? get lunarYear => lunar[0];
int get lunarMonth => lunar[1]; int? get lunarMonth => lunar[1];
int get lunarDay => lunar[2]; int? get lunarDay => lunar[2];
@override @override
String toString() { String toString() {
@ -77,7 +77,7 @@ class DateModel {
//DateTime //DateTime
DateTime getDateTime() { DateTime getDateTime() {
return new DateTime(year, month, day); return new DateTime(year!, month!, day);
} }
//DateTimemodel //DateTimemodel
@ -87,7 +87,7 @@ class DateModel {
..month = dateTime.month ..month = dateTime.month
..day = dateTime.day; ..day = dateTime.day;
List<int> lunar = List<int> lunar =
LunarUtil.solarToLunar(dateModel.year, dateModel.month, dateModel.day); LunarUtil.solarToLunar(dateModel.year!, dateModel.month!, dateModel.day);
dateModel.lunar = lunar; dateModel.lunar = lunar;
// get, // get,

@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
/** /**
* 便 * 便
@ -14,10 +15,9 @@ class LogUtil {
* TAG: * TAG:
* message+ * message+
*/ */
static void log( static void log({required dynamic TAG, String message = ""}) {
{@required dynamic TAG , String message = ""}) { if (_enableLog && kDebugMode) {
if (_enableLog) { debugPrint("flutter_custom_calendar------$TAG------>$message");
print("flutter_custom_calendar------$TAG------>$message");
} }
} }
} }

@ -1,5 +1,6 @@
import 'package:flutter_custom_calendar/model/date_model.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart'; import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
import 'LogUtil.dart';
/** /**
* *
@ -30,7 +31,7 @@ class DateUtil {
* @param month * @param month
* @return * @return
*/ */
static int getMonthDaysCount(int year, int month) { static int getMonthDaysCount(int? year, int? month) {
int count = 0; int count = 0;
// //
if (month == 1 || if (month == 1 ||
@ -50,7 +51,7 @@ class DateUtil {
// //
if (month == 2) { if (month == 2) {
if (isLeapYear(year)) { if (isLeapYear(year!)) {
count = 29; count = 29;
} else { } else {
count = 28; count = 28;
@ -62,7 +63,7 @@ class DateUtil {
/** /**
* *
*/ */
static bool isCurrentDay(int year, int month, int day) { static bool isCurrentDay(int? year, int? month, int day) {
DateTime now = DateTime.now(); DateTime now = DateTime.now();
return now.year == year && now.month == month && now.day == day; return now.year == year && now.month == month && now.day == day;
} }
@ -99,23 +100,25 @@ class DateUtil {
* ,1 * ,1
* @return the start diff with MonthView * @return the start diff with MonthView
*/ */
static int getIndexOfFirstDayInMonth(DateTime dateTime) { static int getIndexOfFirstDayInMonth(DateTime dateTime, {int offset = 0}) {
DateTime firstDayOfMonth = new DateTime(dateTime.year, dateTime.month, 1); DateTime firstDayOfMonth = new DateTime(dateTime.year, dateTime.month, 1);
int week = firstDayOfMonth.weekday; int week = firstDayOfMonth.weekday + offset;
return week; return week;
} }
static List<DateModel> initCalendarForMonthView( static List<DateModel> initCalendarForMonthView(
int year, int month, DateTime currentDate, int weekStart, int year, int month, DateTime currentDate, int weekStart,
{DateModel minSelectDate, {DateModel? minSelectDate,
DateModel maxSelectDate, DateModel? maxSelectDate,
Map<DateModel, Object> extraDataMap}) { Map<DateModel, Object>? extraDataMap,
int offset = 0}) {
print('initCalendarForMonthView start'); print('initCalendarForMonthView start');
weekStart = DateTime.monday; weekStart = DateTime.monday;
// //
int mPreDiff = getIndexOfFirstDayInMonth(new DateTime(year, month)); int mPreDiff =
getIndexOfFirstDayInMonth(new DateTime(year, month), offset: offset);
// //
int monthDayCount = getMonthDaysCount(year, month); int monthDayCount = getMonthDaysCount(year, month);
@ -124,8 +127,7 @@ class DateUtil {
message: message:
"initCalendarForMonthView:$year$month月,有$monthDayCount天,第一天的index为${mPreDiff}"); "initCalendarForMonthView:$year$month月,有$monthDayCount天,第一天的index为${mPreDiff}");
List<DateModel> result = [];
List<DateModel> result = new List();
int size = 42; int size = 42;
@ -136,6 +138,10 @@ class DateUtil {
DateTime temp; DateTime temp;
DateModel dateModel; DateModel dateModel;
if (i < mPreDiff - 1) { if (i < mPreDiff - 1) {
if (i < ((mPreDiff / 7).ceil() - 1) * 7) {
size++;
continue;
}
// //
temp = firstDayOfMonth.subtract(Duration(days: mPreDiff - i - 1)); temp = firstDayOfMonth.subtract(Duration(days: mPreDiff - i - 1));
@ -155,21 +161,21 @@ class DateUtil {
} }
// //
if (dateModel.getDateTime().isAfter(minSelectDate.getDateTime()) && if (dateModel.getDateTime().isAfter(minSelectDate!.getDateTime()) &&
dateModel.getDateTime().isBefore(maxSelectDate.getDateTime())) { dateModel.getDateTime().isBefore(maxSelectDate!.getDateTime())) {
dateModel.isInRange = true; dateModel.isInRange = true;
} else { } else {
dateModel.isInRange = false; dateModel.isInRange = false;
} }
//model //model
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);
@ -183,32 +189,31 @@ class DateUtil {
/** /**
* *
*/ */
static int getMonthViewLineCount(int year, int month) { static int getMonthViewLineCount(int year, int month, int offset) {
DateTime firstDayOfMonth = new DateTime(year, month, 1); DateTime firstDayOfMonth = new DateTime(year, month, 1);
int monthDayCount = getMonthDaysCount(year, month); int monthDayCount = getMonthDaysCount(year, month);
// DateTime lastDayOfMonth = new DateTime(year, month, monthDayCount);
int preIndex = firstDayOfMonth.weekday - 1;
// int lastIndex = lastDayOfMonth.weekday;
int preIndex = (firstDayOfMonth.weekday - 1 + offset) % 7;
int lineCount = ((preIndex + monthDayCount) / 7).ceil();
LogUtil.log( LogUtil.log(
TAG: "DateUtil", TAG: "DateUtil",
message: message: "getMonthViewLineCount:$year$month月:有$lineCount");
"getMonthViewLineCount:$year$month月:有${((preIndex + monthDayCount) / 7).toInt() + 1}");
return ((preIndex + monthDayCount) / 7).toInt() + 1; return lineCount;
} }
/** /**
* 7item * 7item
*/ */
static List<DateModel> initCalendarForWeekView( static List<DateModel> initCalendarForWeekView(
int year, int month, DateTime currentDate, int weekStart, int? year, int? month, DateTime currentDate, int weekStart,
{DateModel minSelectDate, {DateModel? minSelectDate,
DateModel maxSelectDate, DateModel? maxSelectDate,
Map<DateModel, Object> extraDataMap}) { Map<DateModel, Object>? extraDataMap,
List<DateModel> items = List(); int offset = 0}) {
List<DateModel> items = [];
int weekDay = currentDate.weekday; int weekDay = currentDate.weekday + offset;
// //
DateTime firstDayOfWeek = currentDate.add(Duration(days: -weekDay)); DateTime firstDayOfWeek = currentDate.add(Duration(days: -weekDay));
@ -218,8 +223,8 @@ class DateUtil {
DateModel.fromDateTime(firstDayOfWeek.add(Duration(days: i))); DateModel.fromDateTime(firstDayOfWeek.add(Duration(days: i)));
// //
if (dateModel.getDateTime().isAfter(minSelectDate.getDateTime()) && if (dateModel.getDateTime().isAfter(minSelectDate!.getDateTime()) &&
dateModel.getDateTime().isBefore(maxSelectDate.getDateTime())) { dateModel.getDateTime().isBefore(maxSelectDate!.getDateTime())) {
dateModel.isInRange = true; dateModel.isInRange = true;
} else { } else {
dateModel.isInRange = false; dateModel.isInRange = false;
@ -232,7 +237,7 @@ class DateUtil {
//model //model
if (extraDataMap?.isNotEmpty == true) { if (extraDataMap?.isNotEmpty == true) {
if (extraDataMap.containsKey(dateModel)) { if (extraDataMap!.containsKey(dateModel)) {
dateModel.extraData = extraDataMap[dateModel]; dateModel.extraData = extraDataMap[dateModel];
} }
} }

@ -1,11 +1,9 @@
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';
/** ///**
* ///*
*/ ///*/
class LunarUtil { class LunarUtil {
static List<int> LUNAR_MONTH_DAYS = [ static List<int> LUNAR_MONTH_DAYS = [
1887, 1887,
@ -463,14 +461,14 @@ class LunarUtil {
0x107e48 0x107e48
]; ];
/** ////**
* 24 ///* 24
*/ ///*/
static final Map<int, List<String>> SOLAR_TERMS = new Map(); static final Map<int?, List<String?>> SOLAR_TERMS = new Map();
/** ////**
* ///*
*/ ///*/
static List<String> SOLAR_CALENDAR = [ static List<String> SOLAR_CALENDAR = [
"0101元旦", "0101元旦",
"0214情人节", "0214情人节",
@ -508,7 +506,7 @@ class LunarUtil {
/** /**
* , * ,
*/ */
static final Map<int, List<String>> SPECIAL_FESTIVAL = new Map(); static final Map<int?, List<String?>> SPECIAL_FESTIVAL = new Map();
/** /**
* *
@ -758,8 +756,8 @@ class LunarUtil {
* @param calendar calendar * @param calendar calendar
*/ */
static void setupLunarCalendar(DateModel dateModel) { static void setupLunarCalendar(DateModel dateModel) {
int year = dateModel.year; int? year = dateModel.year;
int month = dateModel.month; int? month = dateModel.month;
int day = dateModel.day; int day = dateModel.day;
// dateModel.isWeekend = DateUtil.isWeekend(new DateTime(year, month, day)); // dateModel.isWeekend = DateUtil.isWeekend(new DateTime(year, month, day));
@ -811,7 +809,7 @@ class LunarUtil {
* @return [0] [1] [2] [3] 0 false : 1 true * @return [0] [1] [2] [3] 0 false : 1 true
*/ */
static List<int> solarToLunar(int year, int month, int day) { static List<int> solarToLunar(int year, int month, int day) {
List<int> lunarInt = new List(4); List<int> lunarInt = [0,0,0,0];
int index = year - SOLAR[0]; int index = year - SOLAR[0];
int data = (year << 9) | (month << 5) | (day); int data = (year << 9) | (month << 5) | (day);
int solar11; int solar11;
@ -863,12 +861,12 @@ class LunarUtil {
static int solarToInt(int y, int m, int d) { static int solarToInt(int y, int m, int d) {
m = (m + 9) % 12; m = (m + 9) % 12;
y = y - (m / 10).toInt(); y = y - m ~/ 10;
return (365 * y + return (365 * y +
(y / 4).toInt() - y ~/ 4 -
(y / 100).toInt() + y ~/ 100 +
(y / 400).toInt() + y ~/ 400 +
((m * 306 + 5) / 10).toInt() + (m * 306 + 5) ~/ 10 +
(d - 1)); (d - 1));
} }
@ -880,15 +878,15 @@ class LunarUtil {
* @param day * @param day
* @return 24 * @return 24
*/ */
static String getSolarTerm(int year, int month, int day) { static String getSolarTerm(int? year, int month, int day) {
if (!SOLAR_TERMS.containsKey(year)) { if (!SOLAR_TERMS.containsKey(year)) {
SOLAR_TERMS.addAll({year: SolarTermUtil.getSolarTerms(year)}); SOLAR_TERMS.addAll({year: SolarTermUtil.getSolarTerms(year!)});
} }
List<String> solarTerm = SOLAR_TERMS[year]; List<String?> solarTerm = SOLAR_TERMS[year]!;
String text = "${year}" + getString(month, day); String text = "${year}" + getString(month, day);
String solar = ""; String solar = "";
for (String solarTermName in solarTerm) { for (String? solarTermName in solarTerm) {
if (solarTermName.contains(text)) { if (solarTermName!.contains(text)) {
solar = solarTermName.replaceAll(text, ""); solar = solarTermName.replaceAll(text, "");
break; break;
} }
@ -904,11 +902,11 @@ class LunarUtil {
* @param leap 1== * @param leap 1==
* @return * @return
*/ */
static String numToChinese(int month, int day, int leap) { static String numToChinese(int? month, int? day, int? leap) {
if (day == 1) { if (day == 1) {
return numToChineseMonth(month, leap); return numToChineseMonth(month, leap);
} }
return CalendarConstants.LUNAR_DAY_TEXT[day - 1]; return CalendarConstants.LUNAR_DAY_TEXT[day! - 1];
} }
/** /**
@ -918,11 +916,11 @@ class LunarUtil {
* @param leap 1== * @param leap 1==
* @return * @return
*/ */
static String numToChineseMonth(int month, int leap) { static String numToChineseMonth(int? month, int? leap) {
if (leap == 1) { if (leap == 1) {
return "" + CalendarConstants.LUNAR_MONTH_TEXT[month - 1]; return "" + CalendarConstants.LUNAR_MONTH_TEXT[month! - 1];
} }
return CalendarConstants.LUNAR_MONTH_TEXT[month - 1]; return CalendarConstants.LUNAR_MONTH_TEXT[month! - 1];
} }
static String getString(int month, int day) { static String getString(int month, int day) {
@ -957,14 +955,14 @@ class LunarUtil {
* @param day * @param day
* @return * @return
*/ */
static String getTraditionFestival(int year, int month, int day) { static String getTraditionFestival(int? year, int? month, int? day) {
if (month == 12) { if (month == 12) {
int count = daysInLunarMonth(year, month); int count = daysInLunarMonth(year!, month!);
if (day == count) { if (day == count) {
return TRADITION_FESTIVAL_STR[0]; // return TRADITION_FESTIVAL_STR[0]; //
} }
} }
String text = getString(month, day); String text = getString(month!, day!);
String festivalStr = ""; String festivalStr = "";
for (String festival in TRADITION_FESTIVAL_STR) { for (String festival in TRADITION_FESTIVAL_STR) {
if (festival.contains(text)) { if (festival.contains(text)) {
@ -999,15 +997,15 @@ class LunarUtil {
* @param day day * @param day day
* @return 西 * @return 西
*/ */
static String getSpecialFestival(int year, int month, int day) { static String getSpecialFestival(int? year, int month, int day) {
if (!SPECIAL_FESTIVAL.containsKey(year)) { if (!SPECIAL_FESTIVAL.containsKey(year)) {
SPECIAL_FESTIVAL.addAll({year: getSpecialFestivals(year)}); SPECIAL_FESTIVAL.addAll({year: getSpecialFestivals(year!)});
} }
List<String> specialFestivals = SPECIAL_FESTIVAL[year]; List<String?> specialFestivals = SPECIAL_FESTIVAL[year]!;
String text = "$year" + getString(month, day); String text = "$year" + getString(month, day);
String solar = ""; String solar = "";
for (String special in specialFestivals) { for (String? special in specialFestivals) {
if (special.contains(text)) { if (special!.contains(text)) {
solar = special.replaceAll(text, ""); solar = special.replaceAll(text, "");
break; break;
} }
@ -1022,8 +1020,8 @@ class LunarUtil {
* @param year * @param year
* @return * @return
*/ */
static List<String> getSpecialFestivals(int year) { static List<String?> getSpecialFestivals(int year) {
List<String> festivals = new List(3); List<String?> festivals = ['','',''];
DateTime dateTime = new DateTime(year, 5, 1); DateTime dateTime = new DateTime(year, 5, 1);
// //

@ -15,7 +15,7 @@ class System {
// dest: // dest:
// destPos: // destPos:
// length: // length:
static void arraycopy(List<String> src, int srcPos, List<String> dest, static void arraycopy(List<String?> src, int srcPos, List<String?> dest,
int destPos, int length) { int destPos, int length) {
List.copyRange(dest, destPos, src, srcPos, srcPos+length); List.copyRange(dest, destPos, src, srcPos, srcPos+length);
} }

@ -3,14 +3,8 @@ import 'dart:math';
import 'package:flutter_custom_calendar/utils/math_util.dart'; import 'package:flutter_custom_calendar/utils/math_util.dart';
/**
* http://www.cnblogs.com/moodlxs/archive/2010/12/18/2345392.html
* 24
*/
class SolarTermUtil { class SolarTermUtil {
/** /// 24
* 24
*/
static List<String> SOLAR_TERMS = [ static List<String> SOLAR_TERMS = [
"春分", "春分",
"清明", "清明",
@ -38,25 +32,17 @@ class SolarTermUtil {
"惊蛰", "惊蛰",
]; ];
/** ///
*
*/
static final double SECOND_PER_RAD = 180 * 3600 / pi; static final double SECOND_PER_RAD = 180 * 3600 / pi;
/** ///
*
*/
static final double ANGLE_PER_RAD = 180 / pi; static final double ANGLE_PER_RAD = 180 / pi;
/** ///
* /// * 2000(2000-1-1)
* 2000(2000-1-1)
*/
static final double J2000 = 2451545; static final double J2000 = 2451545;
/** ///
*
*/
static final List<double> H_C_ANGLE_TABLE = [ static final List<double> H_C_ANGLE_TABLE = [
0, 0,
50287.92262, 50287.92262,
@ -68,9 +54,7 @@ class SolarTermUtil {
0.00001 0.00001
]; ];
/** ///
*
*/
static final List<double> DTS = [ static final List<double> DTS = [
-4000, -4000,
108371.7, 108371.7,
@ -212,8 +196,8 @@ class SolarTermUtil {
* @return * @return
*/ */
static double doubleFloor(double v) { static double doubleFloor(double v) {
v = v.floor().toDouble();
if (v < 0) return v + 1; if (v < 0) return v + 1;
return v; return v;
} }
@ -334,14 +318,14 @@ class SolarTermUtil {
* @param jd jd * @param jd jd
* @param zb zb * @param zb zb
*/ */
static void precession(double jd, List<double> zb) { static void precession(double jd, List<double?> zb) {
int i; int i;
double t = 1, v = 0, t1 = jd / 365250; double t = 1, v = 0, t1 = jd / 365250;
for (i = 1; i < 8; i++) { for (i = 1; i < 8; i++) {
t *= t1; t *= t1;
v += H_C_ANGLE_TABLE[i] * t; v += H_C_ANGLE_TABLE[i] * t;
} }
zb[0] = rad2mrad(zb[0] + (v + 2.9965 * t1) / SECOND_PER_RAD); zb[0] = rad2mrad(zb[0]! + (v + 2.9965 * t1) / SECOND_PER_RAD);
} }
/** /**
@ -2017,7 +2001,7 @@ class SolarTermUtil {
*/ */
static List<double> earCal(double jd) { static List<double> earCal(double jd) {
EnnT = jd / 365250; EnnT = jd / 365250;
List<double> llr = new List(3); List<double> llr = [0,0,0];
double t1 = EnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1, t5 = t4 * t1; double t1 = EnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1, t5 = t4 * t1;
llr[0] = Enn(E10) + llr[0] = Enn(E10) +
Enn(E11) * t1 + Enn(E11) * t1 +
@ -2058,16 +2042,16 @@ class SolarTermUtil {
* @param julian * @param julian
* @return return * @return return
*/ */
static List<double> moonCoord(double julian) { static List<double?> moonCoord(double julian) {
MnnT = julian / 36525; MnnT = julian / 36525;
double t1 = MnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1; double t1 = MnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1;
List<double> llr = new List(3); List<double?> llr = [0,0,0];
llr[0] = (Mnn(M10) + Mnn(M11) * t1 + Mnn(M12) * t2) / SECOND_PER_RAD; llr[0] = (Mnn(M10) + Mnn(M11) * t1 + Mnn(M12) * t2) / SECOND_PER_RAD;
llr[1] = (Mnn(M20) + Mnn(M21) * t1) / SECOND_PER_RAD; llr[1] = (Mnn(M20) + Mnn(M21) * t1) / SECOND_PER_RAD;
llr[2] = (Mnn(M30) + Mnn(M31) * t1) * 0.999999949827; llr[2] = (Mnn(M30) + Mnn(M31) * t1) * 0.999999949827;
llr[0] = llr[0] =
llr[0] + M1n[0] + M1n[1] * t1 + M1n[2] * t2 + M1n[3] * t3 + M1n[4] * t4; llr[0]! + M1n[0] + M1n[1] * t1 + M1n[2] * t2 + M1n[3] * t3 + M1n[4] * t4;
llr[0] = rad2mrad(llr[0]); // Date() llr[0] = rad2mrad(llr[0]!); // Date()
precession(julian, llr); // precession(julian, llr); //
return llr; return llr;
} }
@ -2090,8 +2074,8 @@ class SolarTermUtil {
sun[0] += d.Lon; // sun[0] += d.Lon; //
return rad2mrad(angle - sun[0]); return rad2mrad(angle - sun[0]);
} }
List<double> moon = moonCoord(time); // List<double?> moon = moonCoord(time); //
return rad2mrad(angle - (moon[0] - sun[0])); return rad2mrad(angle - (moon[0]! - sun[0]));
} }
/** /**
@ -2139,10 +2123,13 @@ class SolarTermUtil {
* @return 24 * @return 24
*/ */
static List<String> getSolarTerms(int year) { static List<String?> getSolarTerms(int year) {
List<String> solarTerms = new List(24); List<String?> solarTerms = [];
List<String> preOffset = getSolarTermsPreOffset(year - 1); for(int i=0;i<24;i++){
List<String> nextOffset = getSolarTermsNextOffset(year - 1); solarTerms.add('');
}
List<String?> preOffset = getSolarTermsPreOffset(year - 1);
List<String?> nextOffset = getSolarTermsNextOffset(year - 1);
System.arraycopy(preOffset, 0, solarTerms, 0, preOffset.length); System.arraycopy(preOffset, 0, solarTerms, 0, preOffset.length);
System.arraycopy(nextOffset, 0, solarTerms, 22, nextOffset.length); System.arraycopy(nextOffset, 0, solarTerms, 22, nextOffset.length);
@ -2163,8 +2150,8 @@ class SolarTermUtil {
* @param year 2018242017 * @param year 2018242017
* @return * @return
*/ */
static List<String> getSolarTermsPreOffset(int year) { static List<String?> getSolarTermsPreOffset(int year) {
List<String> solarTerms = new List(3); List<String?> solarTerms = ['','',''];
double jd = 365.2422 * (year - 2000), q; double jd = 365.2422 * (year - 2000), q;
for (int i = 21; i < 24; i++) { for (int i = 21; i < 24; i++) {
q = getTimeFromAngle(jd + i * 15.2, i * 15.toDouble(), 0); q = getTimeFromAngle(jd + i * 15.2, i * 15.toDouble(), 0);
@ -2181,8 +2168,8 @@ class SolarTermUtil {
* @param year 2018242017 * @param year 2018242017
* @return * @return
*/ */
static List<String> getSolarTermsNextOffset(int year) { static List<String?> getSolarTermsNextOffset(int year) {
List<String> solarTerms = new List(2); List<String?> solarTerms = ['',''];
double jd = 365.2422 * (year - 2000), q; double jd = 365.2422 * (year - 2000), q;
for (int i = 19; i < 21; i++) { for (int i = 19; i < 21; i++) {
q = getTimeFromAngle(jd + i * 15.2, i * 15.toDouble(), 0); q = getTimeFromAngle(jd + i * 15.2, i * 15.toDouble(), 0);
@ -2201,21 +2188,21 @@ class Nutation {
/** /**
* *
*/ */
double Lon; late double Lon;
/** /**
* *
*/ */
double Obl; late double Obl;
} }
class Time { class Time {
double year; late double year;
double month; late double month;
double day; late double day;
double hour; late double hour;
double minute; late double minute;
double second; late double second;
String toString() { String toString() {
return doubleToString(year) + doubleToString(month) + doubleToString(day); return doubleToString(year) + doubleToString(month) + doubleToString(day);

@ -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
@ -18,7 +20,7 @@ abstract class BaseCustomDayWidget extends StatelessWidget {
child: new CustomPaint( child: new CustomPaint(
painter: painter:
//isSelecteditem //isSelecteditem
dateModel.isSelected dateModel.isSelected!
? new CustomDayWidgetPainter(dateModel, ? new CustomDayWidgetPainter(dateModel,
drawDayWidget: drawSelected) drawDayWidget: drawSelected)
: new CustomDayWidgetPainter(dateModel, : new CustomDayWidgetPainter(dateModel,
@ -35,15 +37,15 @@ abstract class BaseCustomDayWidget extends StatelessWidget {
class CustomDayWidgetPainter extends CustomPainter { class CustomDayWidgetPainter extends CustomPainter {
DateModel dateModel; DateModel dateModel;
DrawDayWidget drawDayWidget; // DrawDayWidget? drawDayWidget; //
CustomDayWidgetPainter(this.dateModel, {this.drawDayWidget}); CustomDayWidgetPainter(this.dateModel, {this.drawDayWidget});
Paint textPaint; Paint? textPaint;
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
drawDayWidget(dateModel, canvas, size); drawDayWidget!(dateModel, canvas, size);
} }
@override @override
@ -62,7 +64,7 @@ abstract class BaseCombineDayWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return dateModel.isSelected return dateModel.isSelected!
? getSelectedWidget(dateModel) ? getSelectedWidget(dateModel)
: getNormalWidget(dateModel); : getNormalWidget(dateModel);
} }

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
* *
*/ */
abstract class BaseWeekBar extends StatelessWidget { abstract class BaseWeekBar extends StatelessWidget {
const BaseWeekBar({Key key}) : super(key: key); const BaseWeekBar({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -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';
/** /**
* *
*/ */
@ -16,14 +19,14 @@ import 'package:provider/provider.dart';
//StatefulWidgetStatelessWidget //StatefulWidgetStatelessWidget
class CalendarViewWidget extends StatefulWidget { class CalendarViewWidget extends StatefulWidget {
// //
final BoxDecoration boxDecoration; final BoxDecoration? boxDecoration;
//paddingmargin //paddingmargin
final EdgeInsetsGeometry padding; final EdgeInsetsGeometry padding;
final EdgeInsetsGeometry margin; final EdgeInsetsGeometry margin;
///7 ///7
final double itemSize; final double? itemSize;
//item10 //item10
final double verticalSpacing; final double verticalSpacing;
@ -36,10 +39,10 @@ class CalendarViewWidget extends StatefulWidget {
final CalendarController calendarController; final CalendarController calendarController;
CalendarViewWidget( CalendarViewWidget(
{Key key, {Key? key,
this.dayWidgetBuilder = defaultCustomDayWidget, this.dayWidgetBuilder = defaultCustomDayWidget,
this.weekBarItemWidgetBuilder = defaultWeekBarWidget, this.weekBarItemWidgetBuilder = defaultWeekBarWidget,
@required this.calendarController, required this.calendarController,
this.boxDecoration, this.boxDecoration,
this.padding = EdgeInsets.zero, this.padding = EdgeInsets.zero,
this.margin = EdgeInsets.zero, this.margin = EdgeInsets.zero,
@ -99,12 +102,12 @@ class CalendarContainer extends StatefulWidget {
class CalendarContainerState extends State<CalendarContainer> class CalendarContainerState extends State<CalendarContainer>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
double itemHeight; double? itemHeight;
double totalHeight; double? totalHeight;
bool expand; late bool expand;
CalendarProvider calendarProvider; late CalendarProvider calendarProvider;
List<Widget> widgets = []; List<Widget> widgets = [];
@ -116,15 +119,15 @@ class CalendarContainerState extends State<CalendarContainer>
calendarProvider = Provider.of<CalendarProvider>(context, listen: false); calendarProvider = Provider.of<CalendarProvider>(context, listen: false);
expand = calendarProvider.expandStatus.value; expand = calendarProvider.expandStatus.value;
if (calendarProvider.calendarConfiguration.showMode == if (calendarProvider.calendarConfiguration!.showMode ==
CalendarConstants.MODE_SHOW_ONLY_WEEK) { CalendarConstants.MODE_SHOW_ONLY_WEEK) {
widgets.add(const WeekViewPager()); widgets.add(const WeekViewPager());
} else if (calendarProvider.calendarConfiguration.showMode == } else if (calendarProvider.calendarConfiguration!.showMode ==
CalendarConstants.MODE_SHOW_WEEK_AND_MONTH) { CalendarConstants.MODE_SHOW_WEEK_AND_MONTH) {
widgets.add(const MonthViewPager()); widgets.add(const MonthViewPager());
widgets.add(const WeekViewPager()); widgets.add(const WeekViewPager());
index = 1; index = 1;
} else if (calendarProvider.calendarConfiguration.showMode == } else if (calendarProvider.calendarConfiguration!.showMode ==
CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) { CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) {
widgets.add(const MonthViewPager()); widgets.add(const MonthViewPager());
widgets.add(const WeekViewPager()); widgets.add(const WeekViewPager());
@ -136,9 +139,9 @@ class CalendarContainerState extends State<CalendarContainer>
expand = calendarProvider.expandStatus.value; expand = calendarProvider.expandStatus.value;
// //
if (calendarProvider.calendarConfiguration.showMode == if (calendarProvider.calendarConfiguration!.showMode ==
CalendarConstants.MODE_SHOW_WEEK_AND_MONTH || CalendarConstants.MODE_SHOW_WEEK_AND_MONTH ||
calendarProvider.calendarConfiguration.showMode == calendarProvider.calendarConfiguration!.showMode ==
CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) { CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) {
calendarProvider.expandStatus.addListener(() { calendarProvider.expandStatus.addListener(() {
setState(() { setState(() {
@ -148,12 +151,12 @@ class CalendarContainerState extends State<CalendarContainer>
if (expand) { if (expand) {
index = 0; index = 0;
// //
calendarProvider.calendarConfiguration.weekController calendarProvider.calendarConfiguration!.weekController!
.jumpToPage(calendarProvider.monthPageIndex); .jumpToPage(calendarProvider.monthPageIndex);
} else { } else {
index = 1; index = 1;
// //
calendarProvider.calendarConfiguration.weekController calendarProvider.calendarConfiguration!.weekController!
.jumpToPage(calendarProvider.weekPageIndex); .jumpToPage(calendarProvider.weekPageIndex);
} }
}); });
@ -163,18 +166,19 @@ class CalendarContainerState extends State<CalendarContainer>
} }
widget.calendarController.addMonthChangeListener((year, month) { widget.calendarController.addMonthChangeListener((year, month) {
if (widget.calendarController.calendarProvider.calendarConfiguration if (widget.calendarController.calendarProvider.calendarConfiguration!
.showMode != .showMode !=
CalendarConstants.MODE_SHOW_ONLY_WEEK) { CalendarConstants.MODE_SHOW_ONLY_WEEK) {
//setState使 //setState使
int lineCount = DateUtil.getMonthViewLineCount(year, month); int lineCount = DateUtil.getMonthViewLineCount(year!, month!,
double newHeight = itemHeight * (lineCount) + widget.calendarController.calendarConfiguration.offset);
calendarProvider.calendarConfiguration.verticalSpacing * double newHeight = itemHeight! * (lineCount) +
calendarProvider.calendarConfiguration!.verticalSpacing! *
(lineCount - 1); (lineCount - 1);
LogUtil.log( LogUtil.log(
TAG: this.runtimeType, TAG: this.runtimeType,
message: "totalHeight:$totalHeight,newHeight:$newHeight"); message: "totalHeight:$totalHeight,newHeight:$newHeight");
if (totalHeight.toInt() != newHeight.toInt()) { if (totalHeight!.toInt() != newHeight.toInt()) {
LogUtil.log(TAG: this.runtimeType, message: "月份视图高度发生变化"); LogUtil.log(TAG: this.runtimeType, message: "月份视图高度发生变化");
setState(() { setState(() {
totalHeight = newHeight; totalHeight = newHeight;
@ -183,7 +187,7 @@ class CalendarContainerState extends State<CalendarContainer>
} }
}); });
itemHeight = calendarProvider.calendarConfiguration.itemSize; itemHeight = calendarProvider.calendarConfiguration!.itemSize;
totalHeight = calendarProvider.totalHeight; totalHeight = calendarProvider.totalHeight;
} }
@ -196,7 +200,7 @@ class CalendarContainerState extends State<CalendarContainer>
Widget build(BuildContext context) { Widget build(BuildContext context) {
LogUtil.log(TAG: this.runtimeType, message: "CalendarContainerState build"); LogUtil.log(TAG: this.runtimeType, message: "CalendarContainerState build");
return Container( return Container(
width: itemHeight * 7, width: itemHeight! * 7,
child: new Column( child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -204,7 +208,7 @@ class CalendarContainerState extends State<CalendarContainer>
/** /**
* constsetStateview * constsetStateview
*/ */
calendarProvider.calendarConfiguration.weekBarItemWidgetBuilder(), calendarProvider.calendarConfiguration!.weekBarItemWidgetBuilder!(),
AnimatedContainer( AnimatedContainer(
duration: Duration(milliseconds: 500), duration: Duration(milliseconds: 500),
height: expand ? totalHeight : itemHeight, height: expand ? totalHeight : itemHeight,

@ -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';
///** ///**
// * // *
// */ // */
@ -39,7 +40,7 @@ import 'package:flutter_custom_calendar/style/style.dart';
//} //}
class DefaultWeekBar extends BaseWeekBar { class DefaultWeekBar extends BaseWeekBar {
const DefaultWeekBar({Key key}) : super(key: key); const DefaultWeekBar({Key? key}) : super(key: key);
@override @override
Widget getWeekBarItem(int index) { Widget getWeekBarItem(int index) {

@ -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';
@ -13,16 +11,16 @@ import 'package:provider/provider.dart';
* *
*/ */
class MonthView extends StatefulWidget { class MonthView extends StatefulWidget {
final int year; final int? year;
final int month; final int? month;
final int day; final int? day;
final CalendarConfiguration configuration; final CalendarConfiguration? configuration;
const MonthView({ const MonthView({
Key key, Key? key,
@required this.year, required this.year,
@required this.month, required this.month,
this.day, this.day,
this.configuration, this.configuration,
}) : super(key: key); }) : super(key: key);
@ -33,37 +31,37 @@ class MonthView extends StatefulWidget {
class _MonthViewState extends State<MonthView> class _MonthViewState extends State<MonthView>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
List<DateModel> items = List(); List<DateModel>? items =[];
int lineCount; int? lineCount;
Map<DateModel, Object> extraDataMap; // Map<DateModel, Object>? extraDataMap; //
@override @override
void initState() { void initState() {
super.initState(); super.initState();
extraDataMap = widget.configuration.extraDataMap; extraDataMap = widget.configuration!.extraDataMap;
DateModel firstDayOfMonth = DateModel firstDayOfMonth =
DateModel.fromDateTime(DateTime(widget.year, widget.month, 1)); DateModel.fromDateTime(DateTime(widget.year!, widget.month!, 1));
if (CacheData.getInstance().monthListCache[firstDayOfMonth]?.isNotEmpty == if (CacheData.getInstance()!.monthListCache[firstDayOfMonth]?.isNotEmpty ==
true) { true) {
LogUtil.log(TAG: this.runtimeType, message: "缓存中有数据"); LogUtil.log(TAG: this.runtimeType, message: "缓存中有数据");
items = CacheData.getInstance().monthListCache[firstDayOfMonth]; items = CacheData.getInstance()!.monthListCache[firstDayOfMonth];
} else { } else {
LogUtil.log(TAG: this.runtimeType, message: "缓存中无数据"); LogUtil.log(TAG: this.runtimeType, message: "缓存中无数据");
getItems().then((_){ getItems().then((_) {
CacheData.getInstance().monthListCache[firstDayOfMonth] = items; CacheData.getInstance()!.monthListCache[firstDayOfMonth] = items;
}); });
} }
lineCount = DateUtil.getMonthViewLineCount(widget.year, widget.month); lineCount = DateUtil.getMonthViewLineCount(
widget.year!, widget.month!, widget.configuration!.offset);
//,generation //,generation
WidgetsBinding.instance.addPostFrameCallback((callback) { WidgetsBinding.instance!.addPostFrameCallback((callback) {
Provider.of<CalendarProvider>(context, listen: false) Provider.of<CalendarProvider>(context, listen: false)
.generation .generation
.addListener(() async { .addListener(() async {
extraDataMap = widget.configuration.extraDataMap; extraDataMap = widget.configuration!.extraDataMap;
await getItems(); await getItems();
}); });
}); });
@ -73,9 +71,10 @@ class _MonthViewState extends State<MonthView>
items = await compute(initCalendarForMonthView, { items = await compute(initCalendarForMonthView, {
'year': widget.year, 'year': widget.year,
'month': widget.month, 'month': widget.month,
'minSelectDate': widget.configuration.minSelectDate, 'minSelectDate': widget.configuration!.minSelectDate,
'maxSelectDate': widget.configuration.maxSelectDate, 'maxSelectDate': widget.configuration!.maxSelectDate,
'extraDataMap': extraDataMap 'extraDataMap': extraDataMap,
'offset': widget.configuration!.offset
}); });
setState(() {}); setState(() {});
} }
@ -85,7 +84,8 @@ class _MonthViewState extends State<MonthView>
map['year'], map['month'], DateTime.now(), DateTime.sunday, map['year'], map['month'], DateTime.now(), DateTime.sunday,
minSelectDate: map['minSelectDate'], minSelectDate: map['minSelectDate'],
maxSelectDate: map['maxSelectDate'], maxSelectDate: map['maxSelectDate'],
extraDataMap: map['extraDataMap']); extraDataMap: map['extraDataMap'],
offset: map['offset']);
} }
@override @override
@ -96,36 +96,65 @@ class _MonthViewState extends State<MonthView>
CalendarProvider calendarProvider = CalendarProvider calendarProvider =
Provider.of<CalendarProvider>(context, listen: false); Provider.of<CalendarProvider>(context, listen: false);
CalendarConfiguration configuration = CalendarConfiguration configuration =
calendarProvider.calendarConfiguration; calendarProvider.calendarConfiguration!;
return new GridView.builder( return new GridView.builder(
addAutomaticKeepAlives: true, addAutomaticKeepAlives: true,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 7, mainAxisSpacing: configuration.verticalSpacing), crossAxisCount: 7, mainAxisSpacing: configuration.verticalSpacing!),
itemCount: items.isEmpty ? 0 : 7 * lineCount, itemCount: items!.isEmpty ? 0 : items!.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
DateModel dateModel = items[index]; DateModel dateModel = items![index];
// //
if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) { switch (configuration.selectMode) {
if (calendarProvider.selectedDateList.contains(dateModel)) {
dateModel.isSelected = true; ///
} else { case CalendarSelectedMode.multiSelect:
dateModel.isSelected = false; if (calendarProvider.selectedDateList!.contains(dateModel)) {
} dateModel.isSelected = true;
} else { } else {
if (calendarProvider.selectDateModel == dateModel) { dateModel.isSelected = false;
dateModel.isSelected = true; }
} else { break;
dateModel.isSelected = false;
} ///
case CalendarSelectedMode.mutltiStartToEndSelect:
if (calendarProvider.selectedDateList!.contains(dateModel)) {
dateModel.isSelected = true;
} else {
dateModel.isSelected = false;
}
break;
///
case CalendarSelectedMode.singleSelect:
if (calendarProvider.selectDateModel == dateModel) {
dateModel.isSelected = true;
} else {
dateModel.isSelected = false;
}
break;
///
case null:
break;
} }
return ItemContainer( return ItemContainer(
dateModel: dateModel, dateModel: dateModel,
key: ObjectKey( key: ObjectKey(dateModel),
dateModel), //使objectKey1flutter2statefulElementstate clickCall: () {
setState(() {});
// if (configuration.selectMode ==
// CalendarSelectedMode.mutltiStartToEndSelect)
///
},
//使objectKey1flutter2statefulElementstate
); );
}); });
} }
@ -138,53 +167,60 @@ class _MonthViewState extends State<MonthView>
* itemitem * itemitem
*/ */
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();
} }
class ItemContainerState extends State<ItemContainer> { class ItemContainerState extends State<ItemContainer> {
DateModel dateModel; DateModel? dateModel;
CalendarConfiguration configuration; CalendarConfiguration? configuration;
CalendarProvider calendarProvider; late CalendarProvider calendarProvider;
ValueNotifier<bool> isSelected; ValueNotifier<bool?>? isSelected;
@override @override
void initState() { void initState() {
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;
// }
// });
} }
/** /**
* item * item
*/ */
void refreshItem() { void refreshItem(bool v) {
/** /**
Exception caught by gesture Exception caught by gesture
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 = !dateModel.isSelected; 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);
} }
} }
@ -203,48 +239,121 @@ class ItemContainerState extends State<ItemContainer> {
message: "GestureDetector onTap: $dateModel}"); message: "GestureDetector onTap: $dateModel}");
// //
if (!dateModel.isInRange) { if (!dateModel!.isInRange) {
// //
if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) { if (configuration!.selectMode == CalendarSelectedMode.multiSelect) {
configuration.multiSelectOutOfRange(); configuration!.multiSelectOutOfRange();
} }
return; return;
} }
calendarProvider.lastClickDateModel = dateModel; calendarProvider.lastClickDateModel = dateModel;
if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) { switch (configuration!.selectMode) {
if (calendarProvider.selectedDateList.contains(dateModel)) { //
calendarProvider.selectedDateList.remove(dateModel); case CalendarSelectedMode.multiSelect:
} else { if (calendarProvider.selectedDateList!.contains(dateModel)) {
// calendarProvider.selectedDateList!.remove(dateModel);
if (calendarProvider.selectedDateList.length == _notifiCationUnCalendarSelect(dateModel);
configuration.maxMultiSelectCount) { } else {
if (configuration.multiSelectOutOfSize != null) { //
configuration.multiSelectOutOfSize(); if (calendarProvider.selectedDateList!.length ==
configuration!.maxMultiSelectCount) {
if (configuration!.multiSelectOutOfSize != null) {
configuration!.multiSelectOutOfSize!();
}
return;
} }
return; dateModel!.isSelected = !dateModel!.isSelected!;
calendarProvider.selectedDateList!.add(dateModel);
} }
calendarProvider.selectedDateList.add(dateModel);
} //
configuration.calendarSelect(dateModel); calendarProvider.selectDateModel = dateModel;
print('多选:${calendarProvider.selectedDateList.toString()}');
// break;
calendarProvider.selectDateModel = dateModel;
} else { ///
calendarProvider.selectDateModel = dateModel; case CalendarSelectedMode.singleSelect:
configuration.calendarSelect(dateModel);
///
//item calendarProvider.selectedDateList!.forEach((element) {
if (calendarProvider.lastClickItemState != this) { element!.isSelected = false;
calendarProvider.lastClickItemState?.refreshItem(); _notifiCationUnCalendarSelect(element);
calendarProvider.lastClickItemState = this; });
} calendarProvider.selectedDateList!.clear();
//item
if (calendarProvider.lastClickItemState != this) {
calendarProvider.lastClickItemState?.refreshItem(false);
calendarProvider.lastClickItemState = this;
}
_notifiCationUnCalendarSelect(calendarProvider.selectDateModel);
dateModel!.isSelected = true;
calendarProvider.selectDateModel = dateModel;
_notifiCationCalendarSelect(dateModel);
setState(() {});
break;
///
case CalendarSelectedMode.mutltiStartToEndSelect:
if (calendarProvider.selectedDateList!.length == 0) {
calendarProvider.selectedDateList!.add(dateModel);
} else if (calendarProvider.selectedDateList!.length == 1) {
DateModel? d2 = calendarProvider.selectedDateList!.first;
if (calendarProvider.selectedDateList!.contains(dateModel)) {
///
dateModel!.isSelected = false;
_notifiCationUnCalendarSelect(dateModel);
setState(() {});
return;
}
DateTime t1, t2;
if (d2!.getDateTime().isAfter(dateModel!.getDateTime())) {
t2 = d2.getDateTime();
t1 = dateModel!.getDateTime();
} else {
t1 = d2.getDateTime();
t2 = dateModel!.getDateTime();
}
for (; t1.isBefore(t2);) {
calendarProvider.selectedDateList!
.add(DateModel.fromDateTime(t1));
t1 = t1.add(Duration(days: 1));
}
calendarProvider.selectedDateList!.add(DateModel.fromDateTime(t1));
} else {
///
calendarProvider.selectedDateList!.forEach((element) {
element!.isSelected = false;
_notifiCationUnCalendarSelect(element);
});
///
calendarProvider.selectedDateList!.clear();
setState(() {});
}
break;
case null:
break;
}
///
if (configuration!.calendarSelect != null &&
calendarProvider.selectedDateList!.length > 0) {
calendarProvider.selectedDateList!.forEach((element) {
_notifiCationCalendarSelect(element);
});
} }
refreshItem(); refreshItem(!this.dateModel!.isSelected!);
}, },
child: configuration.dayWidgetBuilder(dateModel), child: configuration!.dayWidgetBuilder!(dateModel!),
); );
} }

@ -1,13 +1,14 @@
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 {
const MonthViewPager({Key key}) : super(key: key); const MonthViewPager({Key? key}) : super(key: key);
@override @override
_MonthViewPagerState createState() => _MonthViewPagerState(); _MonthViewPagerState createState() => _MonthViewPagerState();
@ -15,7 +16,7 @@ class MonthViewPager extends StatefulWidget {
class _MonthViewPagerState extends State<MonthViewPager> class _MonthViewPagerState extends State<MonthViewPager>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
CalendarProvider calendarProvider; late CalendarProvider calendarProvider;
@override @override
void initState() { void initState() {
@ -62,38 +63,39 @@ class _MonthViewPagerState extends State<MonthViewPager>
// CalendarProvider,listenfalse // CalendarProvider,listenfalse
calendarProvider = Provider.of<CalendarProvider>(context, listen: false); calendarProvider = Provider.of<CalendarProvider>(context, listen: false);
CalendarConfiguration configuration = CalendarConfiguration configuration =
calendarProvider.calendarConfiguration; calendarProvider.calendarConfiguration!;
return PageView.builder( return PageView.builder(
scrollDirection: Axis.vertical,
onPageChanged: (position) { onPageChanged: (position) {
if (calendarProvider.expandStatus.value == false) { if (calendarProvider.expandStatus.value == false) {
return; return;
} }
// //
DateModel dateModel = configuration.monthList[position]; DateModel dateModel = configuration.monthList![position];
configuration.monthChangeListeners.forEach((listener) { configuration.monthChangeListeners!.forEach((listener) {
listener(dateModel.year, dateModel.month); listener(dateModel.year, dateModel.month);
}); });
// //
if (calendarProvider.lastClickDateModel != null || if (calendarProvider.lastClickDateModel != null ||
calendarProvider.lastClickDateModel.month != dateModel.month) { calendarProvider.lastClickDateModel!.month != dateModel.month) {
DateModel temp = new DateModel(); DateModel temp = new DateModel();
temp.year = configuration.monthList[position].year; temp.year = configuration.monthList![position].year;
temp.month = configuration.monthList[position].month; temp.month = configuration.monthList![position].month;
temp.day = configuration.monthList[position].day + 14; temp.day = configuration.monthList![position].day + 14;
calendarProvider.lastClickDateModel = temp; calendarProvider.lastClickDateModel = temp;
} }
}, },
controller: configuration.monthController, controller: configuration.monthController,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final DateModel dateModel = configuration.monthList[index]; final DateModel dateModel = configuration.monthList![index];
return new MonthView( return new MonthView(
configuration: configuration, configuration: configuration,
year: dateModel.year, year: dateModel.year,
month: dateModel.month, month: dateModel.month,
); );
}, },
itemCount: configuration.monthList.length, itemCount: configuration.monthList!.length,
); );
} }

@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
/**
* https://xbuba.com/questions/51712287
*/
class OnlyOnePointerRecognizer extends OneSequenceGestureRecognizer {
int _p = 0;
@override
void addAllowedPointer(PointerDownEvent event) {
startTrackingPointer(event.pointer);
if (_p == 0) {
resolve(GestureDisposition.rejected);
_p = event.pointer;
} else {
resolve(GestureDisposition.accepted);
}
}
@override
String get debugDescription => 'only one pointer recognizer';
@override
void didStopTrackingLastPointer(int pointer) {}
@override
void handleEvent(PointerEvent event) {
if (!event.down && event.pointer == _p) {
_p = 0;
}
}
}
class OnlyOnePointerRecognizerWidget extends StatelessWidget {
final Widget? child;
OnlyOnePointerRecognizerWidget({this.child});
@override
Widget build(BuildContext context) {
return RawGestureDetector(
gestures: <Type, GestureRecognizerFactory>{
OnlyOnePointerRecognizer:
GestureRecognizerFactoryWithHandlers<OnlyOnePointerRecognizer>(
() => OnlyOnePointerRecognizer(),
(OnlyOnePointerRecognizer instance) {
},
),
},
child: child,
);
}
}

@ -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';
@ -11,14 +11,14 @@ import 'package:provider/provider.dart';
* *
*/ */
class WeekView extends StatefulWidget { class WeekView extends StatefulWidget {
final int year; final int? year;
final int month; final int? month;
final DateModel firstDayOfWeek; final DateModel? firstDayOfWeek;
final CalendarConfiguration configuration; final CalendarConfiguration? configuration;
const WeekView( const WeekView(
{@required this.year, {required this.year,
@required this.month, required this.month,
this.firstDayOfWeek, this.firstDayOfWeek,
this.configuration}); this.configuration});
@ -27,31 +27,33 @@ class WeekView extends StatefulWidget {
} }
class _WeekViewState extends State<WeekView> { class _WeekViewState extends State<WeekView> {
List<DateModel> items; late List<DateModel> items;
Map<DateModel, Object> extraDataMap; // Map<DateModel, Object>? extraDataMap; //
@override @override
void initState() { void initState() {
super.initState(); super.initState();
extraDataMap = widget.configuration.extraDataMap; extraDataMap = widget.configuration!.extraDataMap;
items = DateUtil.initCalendarForWeekView( items = DateUtil.initCalendarForWeekView(
widget.year, widget.month, widget.firstDayOfWeek.getDateTime(), 0, widget.year, widget.month, widget.firstDayOfWeek!.getDateTime(), 0,
minSelectDate: widget.configuration.minSelectDate, minSelectDate: widget.configuration!.minSelectDate,
maxSelectDate: widget.configuration.maxSelectDate, maxSelectDate: widget.configuration!.maxSelectDate,
extraDataMap: extraDataMap); extraDataMap: extraDataMap,
offset: widget.configuration!.offset);
//,generation //,generation
WidgetsBinding.instance.addPostFrameCallback((callback) { WidgetsBinding.instance!.addPostFrameCallback((callback) {
Provider.of<CalendarProvider>(context, listen: false) Provider.of<CalendarProvider>(context, listen: false)
.generation .generation
.addListener(() async { .addListener(() async {
items = DateUtil.initCalendarForWeekView( items = DateUtil.initCalendarForWeekView(
widget.year, widget.month, widget.firstDayOfWeek.getDateTime(), 0, widget.year, widget.month, widget.firstDayOfWeek!.getDateTime(), 0,
minSelectDate: widget.configuration.minSelectDate, minSelectDate: widget.configuration!.minSelectDate,
maxSelectDate: widget.configuration.maxSelectDate, maxSelectDate: widget.configuration!.maxSelectDate,
extraDataMap: extraDataMap); extraDataMap: extraDataMap,
offset: widget.configuration!.offset);
setState(() {}); setState(() {});
}); });
}); });
@ -62,7 +64,7 @@ class _WeekViewState extends State<WeekView> {
CalendarProvider calendarProvider = CalendarProvider calendarProvider =
Provider.of<CalendarProvider>(context, listen: false); Provider.of<CalendarProvider>(context, listen: false);
CalendarConfiguration configuration = CalendarConfiguration? configuration =
calendarProvider.calendarConfiguration; calendarProvider.calendarConfiguration;
print( print(
"WeekView Consumer:calendarProvider.selectDateModel:${calendarProvider.selectDateModel}"); "WeekView Consumer:calendarProvider.selectDateModel:${calendarProvider.selectDateModel}");
@ -74,25 +76,39 @@ class _WeekViewState extends State<WeekView> {
itemBuilder: (context, index) { itemBuilder: (context, index) {
DateModel dateModel = items[index]; DateModel dateModel = items[index];
// //
if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) { switch (configuration!.selectMode) {
if (calendarProvider.selectedDateList.contains(dateModel)) { case CalendarSelectedMode.multiSelect:
dateModel.isSelected = true; if (calendarProvider.selectedDateList!.contains(dateModel)) {
} else { dateModel.isSelected = true;
dateModel.isSelected = false; } else {
} dateModel.isSelected = false;
} else { }
if (calendarProvider.selectDateModel == dateModel) { break;
dateModel.isSelected = true; case CalendarSelectedMode.singleSelect:
} else { if (calendarProvider.selectDateModel == dateModel) {
dateModel.isSelected = false; dateModel.isSelected = true;
} } else {
dateModel.isSelected = false;
}
break;
case CalendarSelectedMode.mutltiStartToEndSelect:
if (calendarProvider.selectedDateList!.contains(dateModel)) {
dateModel.isSelected = true;
} else {
dateModel.isSelected = false;
}
break;
case null:
break;
} }
return ItemContainer( return ItemContainer(
dateModel: dateModel, dateModel: dateModel,
// configuration: configuration, clickCall: () {
// calendarProvider: calendarProvider, setState(() {});
); });
}); });
} }
} }

@ -1,13 +1,13 @@
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);
@override @override
_WeekViewPagerState createState() => _WeekViewPagerState(); _WeekViewPagerState createState() => _WeekViewPagerState();
@ -15,8 +15,8 @@ class WeekViewPager extends StatefulWidget {
class _WeekViewPagerState extends State<WeekViewPager> class _WeekViewPagerState extends State<WeekViewPager>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
int lastMonth; // int? lastMonth; //
CalendarProvider calendarProvider; late CalendarProvider calendarProvider;
// PageController newPageController; // PageController newPageController;
@ -27,7 +27,7 @@ class _WeekViewPagerState extends State<WeekViewPager>
calendarProvider = Provider.of<CalendarProvider>(context, listen: false); calendarProvider = Provider.of<CalendarProvider>(context, listen: false);
lastMonth = calendarProvider.lastClickDateModel.month; lastMonth = calendarProvider.lastClickDateModel!.month;
} }
@override @override
@ -45,7 +45,7 @@ class _WeekViewPagerState extends State<WeekViewPager>
CalendarProvider calendarProvider = CalendarProvider calendarProvider =
Provider.of<CalendarProvider>(context, listen: false); Provider.of<CalendarProvider>(context, listen: false);
CalendarConfiguration configuration = CalendarConfiguration configuration =
calendarProvider.calendarConfiguration; calendarProvider.calendarConfiguration!;
return Container( return Container(
height: configuration.itemSize ?? MediaQuery.of(context).size.width / 7, height: configuration.itemSize ?? MediaQuery.of(context).size.width / 7,
@ -59,10 +59,10 @@ class _WeekViewPagerState extends State<WeekViewPager>
TAG: this.runtimeType, TAG: this.runtimeType,
message: message:
"WeekViewPager PageView onPageChanged,position:$position"); "WeekViewPager PageView onPageChanged,position:$position");
DateModel firstDayOfWeek = configuration.weekList[position]; DateModel firstDayOfWeek = configuration.weekList![position];
int currentMonth = firstDayOfWeek.month; int? currentMonth = firstDayOfWeek.month;
// //
configuration.weekChangeListeners.forEach((listener) { configuration.weekChangeListeners!.forEach((listener) {
listener(firstDayOfWeek.year, firstDayOfWeek.month); listener(firstDayOfWeek.year, firstDayOfWeek.month);
}); });
if (lastMonth != currentMonth) { if (lastMonth != currentMonth) {
@ -70,12 +70,12 @@ class _WeekViewPagerState extends State<WeekViewPager>
TAG: this.runtimeType, TAG: this.runtimeType,
message: message:
"WeekViewPager PageView monthChange:currentMonth:$currentMonth"); "WeekViewPager PageView monthChange:currentMonth:$currentMonth");
configuration.monthChangeListeners.forEach((listener) { configuration.monthChangeListeners!.forEach((listener) {
listener(firstDayOfWeek.year, firstDayOfWeek.month); listener(firstDayOfWeek.year, firstDayOfWeek.month);
}); });
lastMonth = currentMonth; lastMonth = currentMonth;
if (calendarProvider.lastClickDateModel == null || if (calendarProvider.lastClickDateModel == null ||
calendarProvider.lastClickDateModel.month != currentMonth) { calendarProvider.lastClickDateModel!.month != currentMonth) {
DateModel temp = new DateModel(); DateModel temp = new DateModel();
temp.year = firstDayOfWeek.year; temp.year = firstDayOfWeek.year;
temp.month = firstDayOfWeek.month; temp.month = firstDayOfWeek.month;
@ -86,9 +86,9 @@ class _WeekViewPagerState extends State<WeekViewPager>
// calendarProvider.lastClickDateModel = configuration.weekList[position] // calendarProvider.lastClickDateModel = configuration.weekList[position]
// ..day += 4; // ..day += 4;
}, },
controller: calendarProvider.calendarConfiguration.weekController, controller: calendarProvider.calendarConfiguration!.weekController,
itemBuilder: (context, index) { itemBuilder: (context, index) {
DateModel dateModel = configuration.weekList[index]; DateModel dateModel = configuration.weekList![index];
return new WeekView( return new WeekView(
year: dateModel.year, year: dateModel.year,
month: dateModel.month, month: dateModel.month,
@ -96,7 +96,7 @@ class _WeekViewPagerState extends State<WeekViewPager>
configuration: calendarProvider.calendarConfiguration, configuration: calendarProvider.calendarConfiguration,
); );
}, },
itemCount: configuration.weekList.length, itemCount: configuration.weekList!.length,
), ),
); );
} }

@ -1,62 +1,55 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
archive:
dependency: transitive
description:
name: archive
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.10"
args:
dependency: transitive
description:
name: args
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.5.2"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.3.0" version: "2.6.1"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.1.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.2" version: "1.2.0"
collection: clock:
dependency: transitive dependency: transitive
description: description:
name: collection name: clock
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.11" version: "1.1.0"
convert: collection:
dependency: transitive dependency: transitive
description: description:
name: convert name: collection
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "1.15.0"
crypto: fake_async:
dependency: transitive dependency: transitive
description: description:
name: crypto name: fake_async
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.3" version: "1.2.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -67,62 +60,41 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
image:
dependency: transitive
description:
name: image
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.5" version: "0.12.10"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted
version: "1.1.7"
path:
dependency: transitive
description:
name: path
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.6.4" version: "1.3.0"
pedantic: nested:
dependency: transitive dependency: transitive
description: description:
name: pedantic name: nested
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0+1" version: "1.0.0"
petitparser: path:
dependency: transitive dependency: transitive
description: description:
name: petitparser name: path
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.0" version: "1.8.0"
provider: provider:
dependency: "direct main" dependency: "direct main"
description: description:
name: provider name: provider
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.0+1" version: "6.0.3"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.5"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -132,64 +104,58 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.5" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.3" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.1.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.5" version: "0.3.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.6" version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.5.0" version: "2.1.0"
sdks: sdks:
dart: ">=2.4.0 <3.0.0" dart: ">=2.12.0 <3.0.0"
flutter: ">=1.16.0"

@ -1,53 +1,54 @@
name: flutter_custom_calendar name: flutter_custom_calendar
description: A new Flutter Calendar package. description: A calendar control of flutter that supports three selection modes
version: 0.0.1 version: 1.0.4+0.5
author: xiaodong <450468291@qq.com> homepage: http://www.fgyong.cn
homepage: https://github.com/LXD312569496/flutter_custom_calendar author: fgyong
repository: https://github.com/ifgyong/flutter_custom_calendar
issue_tracker: https://github.com/ifgyong/flutter_custom_calendar/issues
environment: environment:
sdk: ">=2.1.0 <3.0.0" sdk: '>=2.12.0 <3.0.0'
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
provider: ^3.1.0+1
provider: ^6.0.2
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://www.dartlang.org/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter. # The following section is specific to Flutter.
flutter: flutter:
# To add assets to your package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# To add assets to your package, add an assets section, like this: # To add custom fonts to your package, add a fonts section here,
# assets: # in this "flutter" section. Each entry in this list should have a
# - images/a_dot_burr.jpeg # "family" key with the font family name, and a "fonts" key with a
# - images/a_dot_ham.jpeg # list giving the asset and other descriptors for the font. For
# # example:
# For details regarding assets in packages, see # fonts:
# https://flutter.dev/assets-and-images/#from-packages # - family: Schyler
# # fonts:
# An image asset can refer to one or more resolution-specific "variants", see # - asset: fonts/Schyler-Regular.ttf
# https://flutter.dev/assets-and-images/#resolution-aware. # - asset: fonts/Schyler-Italic.ttf
# style: italic
# To add custom fonts to your package, add a fonts section here, # - family: Trajan Pro
# in this "flutter" section. Each entry in this list should have a # fonts:
# "family" key with the font family name, and a "fonts" key with a # - asset: fonts/TrajanPro.ttf
# list giving the asset and other descriptors for the font. For # - asset: fonts/TrajanPro_Bold.ttf
# example: # weight: 700
# fonts: #
# - family: Schyler # For details regarding fonts in packages, see
# fonts: # https://flutter.dev/custom-fonts/#from-packages
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages

@ -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