Compare commits

..

No commits in common. 'master' and 'develop' have entirely different histories.

@ -1,116 +0,0 @@
<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,10 +21,11 @@
<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,198 +5,174 @@
<entry key="async"> <entry key="async">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/async-2.6.1/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/async-2.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="boolean_selector"> <entry key="boolean_selector">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/boolean_selector-1.0.4/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="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/charcode-1.1.2/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="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/collection-1.14.11/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="cupertino_icons"> <entry key="cupertino_icons">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/cupertino_icons-0.1.3/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/cupertino_icons-0.1.2/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="/Applications/sdk/flutter/packages/flutter/lib" /> <option value="$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_test"> <entry key="flutter_test">
<value> <value>
<list> <list>
<option value="/Applications/sdk/flutter/packages/flutter_test/lib" /> <option value="$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter_test/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="matcher"> <entry key="matcher">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/matcher-0.12.10/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/matcher-0.12.5/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="meta"> <entry key="meta">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/meta-1.3.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/meta-1.1.6/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="nested"> <entry key="path">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/path-1.6.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path"> <entry key="pedantic">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/pedantic-1.5.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="provider"> <entry key="quiver">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/provider-6.0.3/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/quiver-2.0.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="sky_engine"> <entry key="sky_engine">
<value> <value>
<list> <list>
<option value="/Applications/sdk/flutter/bin/cache/pkg/sky_engine/lib" /> <option value="$PROJECT_DIR$/../../FlutterSDK/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="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/source_span-1.8.1/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/source_span-1.5.5/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="stack_trace"> <entry key="stack_trace">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/stack_trace-1.9.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="stream_channel"> <entry key="stream_channel">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/stream_channel-2.0.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="string_scanner"> <entry key="string_scanner">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/string_scanner-1.0.4/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="term_glyph"> <entry key="term_glyph">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/term_glyph-1.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="test_api"> <entry key="test_api">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/test_api-0.3.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/test_api-0.2.4/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="typed_data"> <entry key="typed_data">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/typed_data-1.1.6/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="vector_math"> <entry key="vector_math">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.0/lib" /> <option value="$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/vector_math-2.0.8/lib" />
</list> </list>
</value> </value>
</entry> </entry>
</option> </option>
</properties> </properties>
<CLASSES> <CLASSES>
<root url="file:///Applications/sdk/flutter/bin/cache/pkg/sky_engine/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/async-2.1.0/lib" />
<root url="file:///Applications/sdk/flutter/packages/flutter/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_test/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.flutter-io.cn/charcode-1.1.2/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/collection-1.14.11/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/cupertino_icons-0.1.2/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/matcher-0.12.5/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/meta-1.1.6/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/path-1.6.2/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/pedantic-1.5.0/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/quiver-2.0.2/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/source_span-1.5.5/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/stack_trace-1.9.3/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/stream_channel-2.0.0/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/string_scanner-1.0.4/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/term_glyph-1.1.0/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/test_api-0.2.4/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/typed_data-1.1.6/lib" />
<root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/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/stream_channel-2.1.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/string_scanner-1.1.0/lib" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter/lib" />
<root url="file://$PROJECT_DIR$/../.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/packages/flutter_test/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:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/async" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/async" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/cli" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/cli" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/collection" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/convert" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/core" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/core" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/developer" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/ffi" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/ffi" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/html" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/html" />
<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/indexed_db" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/io" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/io" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/isolate" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/isolate" />
<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" />
<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/js_util" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/math" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/math" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/mirrors" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/svg" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/svg" />
<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/typed_data" />
<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_audio" />
<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_gl" />
<root url="file:///Applications/sdk/flutter/bin/cache/dart-sdk/lib/web_sql" /> <root url="file://$PROJECT_DIR$/../../FlutterSDK/flutter/bin/cache/dart-sdk/lib/web_sql" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -1,10 +0,0 @@
<?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>

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

@ -1,44 +1,172 @@
<?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="Default Changelist"> <list default="true" id="18463f0e-cf10-4ee2-975b-376476396e12" name="Default Changelist" comment="">
<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$/lib/model/date_model.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/model/date_model.dart" afterDir="false" /> <change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" 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="ProjectId" id="1dLYXgUqXFRhtM2vVF7WEPgjPS2" /> <component name="IdeDocumentHistory">
<component name="ProjectReloadState"> <option name="CHANGED_PATHS">
<option name="STATE" value="1" /> <list>
<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="ProjectViewState"> <component name="ProjectView">
<option name="hideEmptyMiddlePackages" value="true" /> <navigator currentView="ProjectPane" proportions="" version="1">
<option name="showLibraryContents" value="true" /> <foldersAlwaysOnTop 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="RunOnceActivity.OpenProjectViewOnStart" value="true" /> <property name="android.sdk.path" value="$USER_HOME$/Library/Android/sdk" />
<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="flutter.settings" /> <property name="settings.editor.selected.configurable" value="preferences.pluginManager" />
<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">
@ -49,6 +177,18 @@
<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" />
@ -64,7 +204,6 @@
</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>
@ -78,16 +217,209 @@
</task> </task>
<servers /> <servers />
</component> </component>
<component name="Vcs.Log.Tabs.Properties"> <component name="ToolWindowManager">
<option name="TAB_STATES"> <frame x="0" y="23" width="1440" height="806" extended-state="0" />
<map> <editor active="true" />
<entry key="MAIN"> <layout>
<value> <window_info id="Captures" order="0" side_tool="true" weight="0.25" />
<State /> <window_info active="true" content_ui="combo" id="Project" order="1" visible="true" weight="0.3040057" />
</value> <window_info id="Structure" order="2" side_tool="true" />
</entry> <window_info id="Image Layers" order="3" />
</map> <window_info id="Designer" order="4" />
</option> <window_info id="Resources Explorer" order="5" />
<option name="oldMeFiltersMigrated" value="true" /> <window_info id="Capture Tool" order="6" />
<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,8 +74,7 @@
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})
``` ```
#### 通用参数说明 #### 通用参数说明
@ -95,12 +94,11 @@
| 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,8 +73,7 @@ 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
@ -99,7 +98,6 @@ 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,5 +1,26 @@
## [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,90 +1,138 @@
## flutter_custom_calendar
> 本插件是基于[flutter_custom_calendar](https://github.com/fluttercandies/flutter_custom_calendar)做了稍微的修改进行上传的。
具体使用方法见[flutter_custom_calendar](https://github.com/ifgyong/flutter_custom_calendar)
新增一个选择`mode`
支持选择开始和结束,选择范围内的日期,使用方法
## FlutterCalendarWidget
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文件里面添加依赖:
``` ```
controller = new CalendarController( flutter_custom_calendar:
minYear: 2019, git:
minYearMonth: 1, url: https://github.com/LXD312569496/flutter_custom_calendar.git
maxYear: 2021,
maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK,
selectedDateTimeList: _selectedDate,
selectMode: CalendarSelectedMode.mutltiStartToEndSelect)
..addOnCalendarSelectListener((dateModel) {
_selectedModels.add(dateModel);
})
..addOnCalendarUnSelectListener((dateModel) {
if (_selectedModels.contains(dateModel)) {
_selectedModels.remove(dateModel);
}
});
``` ```
`CalendarSelectedMode.mutltiStartToEndSelect`这个选择模式会选择开始和结束中间的 默认选择的。
### 安装和使用
Use this package as a library
1. Depend on it
Add this to your package's pubspec.yaml file:
2.导入flutter_custom_calendar库
``` ```
dependencies: import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
flutter_custom_calendar: ^1.0.4+0.5
``` ```
2. Install it 3.创建CalendarViewWidget对象配置CalendarController
You can install packages from the command line:
with Flutter:
``` ```
$ flutter pub get CalendarController controller= new CalendarController(
minYear: 2018,
minYearMonth: 1,
maxYear: 2020,
maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_MONTH_AND_WEEK);
CalendarViewWidget calendar= CalendarViewWidget(
calendarController: controller,
),
``` ```
Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more. * boxDecoration用来配置整体的背景
* 利用CalendarController来配置一些数据并且可以通过CalendarController进行一些操作或者事件监听比如滚动到下一个月获取当前被选中的Item等等。
3. Import it
Now in your Dart code, you can use:
4.操作日历
``` ```
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart'; controller.toggleExpandStatus();//月视图和周视图的切换
``` ```
### 监听月视图和周视图状态
```dart WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
controller.addExpandChangeListener((value) {
/// 添加改变 月视图和 周视图的监听
_isMonthSelected = value;
setState(() {});
});
});
``` ```
### 变更月视图和周视图 controller.previousPage();//操作日历切换到上一页
> 前提条件是`showModel`是`CalendarConstants.MODE_SHOW_MONTH_AND_WEEK`或者`CalendarConstants.MODE_SHOW_WEEK_AND_MONTH`.
#### 变更到周视图
```dart
setState(() {
controller.weekAndMonthViewChange(CalendarConstants.MODE_SHOW_ONLY_WEEK);
});
``` ```
#### 变更到月视图
```dart
setState(() {controller.weekAndMonthViewChange(CalendarConstants.MODE_SHOW_ONLY_MONTH);
});
``` ```
controller.nextPage();//操作日历切换到下一页
```
## 2.0版本
主要改动:
* UI配置相关的参数移动到CalendarView的构造方法里面旧版本是在controller里面配置
* 日历支持padding和margin属性item的大小计算修改
* 实现日历整体自适应高度
* controller提供changeExtraDataMap的方法可以随时动态的修改自定义数据extraDataMap
* 支持显示月视图和周视图的情况优先显示周视图MODE_SHOW_WEEK_AND_MONTH
* 支持verticalSpacing和itemSize属性
## 注意事项
* 如果使用2.0之前的版本则需要将UI配置相关的参数移动到CalendarView的构造方法里面旧版本是在controller里面配置
* 暂时没有发现其他问题,如果有其他问题,可以跟我说一下。
* 如果你用这个库做了日历,可以将展示结果分享给我,我贴到文档上进行展示
## 主要API文档
### 动画演示 [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

@ -0,0 +1,36 @@
# 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

@ -1,116 +0,0 @@
<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>

@ -1,15 +0,0 @@
<?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>

@ -1,252 +0,0 @@
<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>

@ -1,29 +0,0 @@
<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>

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

@ -1,8 +0,0 @@
<?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>

@ -1,49 +0,0 @@
<?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>

@ -0,0 +1,10 @@
# 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 @@
# example # example1
flutter_custom_calendar/example A new Flutter project.
## Getting Started ## Getting Started

@ -22,22 +22,28 @@ 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.example" applicationId "com.example.example1"
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 {
@ -52,3 +58,10 @@ 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.example"> package="com.example.example1">
<!-- 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.example"> package="com.example.example1">
<!-- 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="example" android:label="example1"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
@ -16,32 +16,17 @@
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">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- This keeps the window background of the activity showing
the Android process has started. This theme is visible to the user until Flutter renders its first frame. It can be removed if
while the Flutter UI initializes. After that, this theme continues there is no splash screen (such as the default splash screen
to determine the Window background behind the Flutter UI. --> defined in @style/LaunchTheme). -->
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:resource="@style/NormalTheme" android:value="true" />
/>
<!-- 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>

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

@ -0,0 +1,12 @@
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,18 +1,8 @@
<?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.example"> package="com.example.example1">
<!-- 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,4 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.3.50'
repositories { repositories {
google() google()
jcenter() jcenter()
@ -6,6 +7,7 @@ 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"
} }
} }

@ -1,25 +0,0 @@
<?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>

@ -1,18 +0,0 @@
<?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>

@ -1,17 +0,0 @@
<?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,7 +9,11 @@
/* 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 */; };
@ -22,6 +26,8 @@
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;
@ -32,11 +38,13 @@
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>"; };
@ -49,6 +57,8 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -58,7 +68,9 @@
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 */,
@ -136,7 +148,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1020; LastUpgradeCheck = 1020;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
@ -145,7 +157,7 @@
}; };
}; };
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3"; compatibilityVersion = "Xcode 3.2";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
@ -189,7 +201,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
}; };
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
@ -308,7 +320,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_BUNDLE_IDENTIFIER = com.example.example1;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -442,7 +454,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_BUNDLE_IDENTIFIER = com.example.example1;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -469,7 +481,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.example.example; PRODUCT_BUNDLE_IDENTIFIER = com.example.example1;
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;

@ -1,8 +0,0 @@
<?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>

@ -1,8 +0,0 @@
<?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>

@ -1,8 +0,0 @@
<?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>

@ -1,8 +0,0 @@
<?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>example</string> <string>example1</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>

@ -0,0 +1,253 @@
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,
),
),
),
],
),
],
),
);
}
}

@ -0,0 +1,244 @@
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()
],
),
);
}
}

@ -0,0 +1,190 @@
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));
}
}

@ -0,0 +1,102 @@
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,12 +1,17 @@
import 'dart:collection'; import 'only_week_page.dart';
import 'red_style_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/constants/constants.dart'; import 'blue_style_page.dart';
import 'package:flutter_custom_calendar/controller.dart'; import 'custom_sign_page.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart'; import 'custom_style_page.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());
} }
@ -15,244 +20,95 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'Flutter Demo', // checkerboardOffscreenLayers: true, // 使saveLayer
theme: ThemeData( routes: <String, WidgetBuilder>{
"/default": (context) => DefaultStylePage(
title: "默认风格+单选",
),
"/custom": (context) => CustomStylePage(
title: "自定义风格+单选",
),
"/multi_select": (context) => MultiSelectStylePage(
title: "自定义风格+多选",
),
"/progress": (context) => ProgressStylePage(
title: "进度条风格+单选",
),
"/custom_sign": (context) => CustomSignPage(
title: "自定义额外数据,实现标记功能",
),
"/only_week_view": (context) => OnlyWeekPage(
title: "仅显示周视图",
),
"/blue_style_page": (context) => BlueStylePage(title: "蓝色背景Demo"),
"/red_style_page": (context) => RedStylePage(title: "蓝色背景Demo"),
},
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity, ),
focusColor: Colors.teal), home: HomePage());
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
} }
} }
class MyHomePage extends StatefulWidget { class HomePage extends StatelessWidget {
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
void initState() {
_selectedDate.add(DateTime.now());
controller = new CalendarController(
minYear: 2019,
minYearMonth: 1,
maxYear: 2021,
maxYearMonth: 12,
showMode: CalendarConstants.MODE_SHOW_WEEK_AND_MONTH,
selectedDateTimeList: _selectedDate,
selectMode: CalendarSelectedMode.singleSelect)
..addOnCalendarSelectListener((dateModel) {
_selectedModels.add(dateModel);
setState(() {
_selectDate = _selectedModels.toString();
});
})
..addOnCalendarUnSelectListener((dateModel) {
if (_selectedModels.contains(dateModel)) {
_selectedModels.remove(dateModel);
}
setState(() {
_selectDate = '';
});
});
calendar = new CalendarViewWidget(
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()),
],
),
),
);
},
);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
controller.addExpandChangeListener((value) {
///
_isMonthSelected = value;
setState(() {});
});
});
super.initState();
}
bool _isMonthSelected = false;
String _selectDate = '';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return new Scaffold(
appBar: AppBar( body: SafeArea(
title: Text(widget.title), child: new Column(
), children: <Widget>[
body: CupertinoScrollbar( new RaisedButton(
child: CustomScrollView( onPressed: () {
slivers: <Widget>[ Navigator.pushNamed(context, "/default");
_topButtons(), },
_topMonths(), child: new Text("默认风格+单选"),
SliverToBoxAdapter(
child: calendar,
), ),
SliverToBoxAdapter( new RaisedButton(
child: Container( onPressed: () {
child: Text( Navigator.pushNamed(context, "/custom");
' $_selectDate ', },
style: TextStyle(color: Theme.of(context).focusColor), child: new Text("自定义风格+单选"),
), ),
), new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/multi_select");
},
child: new Text("自定义风格+多选"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/progress");
},
child: new Text("进度条风格+单选"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/custom_sign");
},
child: new Text("自定义额外数据,实现标记功能"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/only_week_view");
},
child: new Text("仅显示周视图"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/blue_style_page");
},
child: new Text("蓝色Demo"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/red_style_page");
},
child: new Text("红色Demo"),
) )
], ],
), ),
), ),
); );
} }
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,
),
],
),
],
),
);
}
} }

@ -0,0 +1,185 @@
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));
}
}

@ -0,0 +1,102 @@
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.
);
}
}

@ -0,0 +1,224 @@
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));
}
}

@ -0,0 +1,238 @@
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,62 +1,69 @@
# 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.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.6.1" version: "2.3.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "1.0.5"
characters: charcode:
dependency: transitive dependency: transitive
description: description:
name: characters name: charcode
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.1.2"
charcode: collection:
dependency: transitive dependency: transitive
description: description:
name: charcode name: collection
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.14.11"
clock: convert:
dependency: transitive dependency: transitive
description: description:
name: clock name: convert
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "2.1.1"
collection: crypto:
dependency: transitive dependency: transitive
description: description:
name: collection name: crypto
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.15.0" version: "2.1.3"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
name: cupertino_icons name: cupertino_icons
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.3" version: "0.1.2"
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
@ -68,47 +75,75 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "1.0.4+0.5" version: "0.0.1"
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.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10" version: "0.12.5"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0" version: "1.1.7"
nested: path:
dependency: transitive dependency: transitive
description: description:
name: nested name: path
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.0.0" version: "1.6.4"
path: pedantic:
dependency: transitive dependency: transitive
description: description:
name: path name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0" version: "1.8.0+1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.0"
provider: provider:
dependency: transitive dependency: transitive
description: description:
name: provider name: provider
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
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: "6.0.3" version: "0.0.3"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -118,58 +153,64 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.1" version: "1.5.5"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.10.0" version: "1.9.3"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "2.0.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.0.5"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.1.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.3.0" version: "0.2.5"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0" version: "1.1.6"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.8"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "3.5.0"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.4.0 <3.0.0"
flutter: ">=1.16.0"

@ -1,9 +1,5 @@
name: example name: example1
description: flutter_custom_calendar example description: A new Flutter project.
# 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
@ -18,24 +14,23 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1 version: 1.0.0+1
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.1.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.3 cupertino_icons: ^0.1.2
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
@ -49,8 +44,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,21 +8,23 @@
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);
// }); });
} }

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

@ -1,26 +0,0 @@
<?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.

Before

Width:  |  Height:  |  Size: 736 KiB

@ -1,4 +1,4 @@
import 'model/date_model.dart'; import 'package:flutter_custom_calendar/model/date_model.dart';
/** /**
* *
@ -7,23 +7,28 @@ 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 'model/date_model.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,37 +102,36 @@ class CalendarProvider extends ChangeNotifier {
return index + 1; return index + 1;
} }
late ValueNotifier<bool> expandStatus; // 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,
required CalendarConfiguration calendarConfiguration, 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
@ -152,16 +151,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 {
@ -174,11 +173,9 @@ class CalendarProvider extends ChangeNotifier {
calendarConfiguration.showMode == calendarConfiguration.showMode ==
CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) { CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) {
int lineCount = DateUtil.getMonthViewLineCount( int lineCount = DateUtil.getMonthViewLineCount(
calendarConfiguration.nowYear!, calendarConfiguration.nowYear, calendarConfiguration.nowMonth);
calendarConfiguration.nowMonth!, totalHeight = calendarConfiguration.itemSize * (lineCount) +
calendarConfiguration.offset); calendarConfiguration.verticalSpacing * (lineCount - 1);
totalHeight = calendarConfiguration.itemSize! * (lineCount) +
calendarConfiguration.verticalSpacing! * (lineCount - 1);
} else { } else {
totalHeight = calendarConfiguration.itemSize; totalHeight = calendarConfiguration.itemSize;
} }
@ -187,8 +184,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,90 +1,82 @@
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
CalendarSelectedMode? selectMode; int 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; //
OnCalendarSelect? unCalendarSelect; // OnMultiSelectOutOfRange multiSelectOutOfRange; //
late OnMultiSelectOutOfRange multiSelectOutOfRange; // OnMultiSelectOutOfSize multiSelectOutOfSize; //
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 = []; //list List<DateModel> monthList = new List(); //list
List<DateModel>? weekList = [] ; //list List<DateModel> weekList = new List(); //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,
@ -112,8 +104,7 @@ 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,23 +1,15 @@
enum CalendarSelectedMode { singleSelect, multiSelect, mutltiStartToEndSelect }
class CalendarConstants { 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_MULTI_SELECT_START_TO_END = 3;
// //
static const int MODE_SHOW_ONLY_MONTH = 1; // static const int MODE_SHOW_ONLY_MONTH=1;//
static const int MODE_SHOW_ONLY_WEEK = 2; // static const int MODE_SHOW_ONLY_WEEK=2;//
static const int MODE_SHOW_WEEK_AND_MONTH = 3; // static const int MODE_SHOW_WEEK_AND_MONTH=3;//
static const int MODE_SHOW_MONTH_AND_WEEK = 4; // static const int MODE_SHOW_MONTH_AND_WEEK=4;//
/** /**
* *

@ -1,17 +1,15 @@
import 'dart:collection'; import 'dart:collection';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'calendar_provider.dart'; import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'configuration.dart'; import 'package:flutter_custom_calendar/configuration.dart';
import 'constants/constants.dart'; import 'package:flutter_custom_calendar/constants/constants.dart';
import 'flutter_custom_calendar.dart'; import 'package:flutter_custom_calendar/model/date_model.dart';
import 'utils/LogUtil.dart'; import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'utils/date_util.dart'; import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'widget/default_combine_day_view.dart'; import 'package:flutter_custom_calendar/widget/default_combine_day_view.dart';
import 'widget/default_custom_day_view.dart'; import 'package:flutter_custom_calendar/widget/default_custom_day_view.dart';
import 'widget/default_week_bar.dart'; import 'package:flutter_custom_calendar/widget/default_week_bar.dart';
import 'model/date_model.dart';
/** /**
* controller * controller
@ -22,27 +20,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);
late CalendarConfiguration calendarConfiguration; CalendarConfiguration calendarConfiguration;
CalendarProvider calendarProvider = CalendarProvider(); CalendarProvider calendarProvider = CalendarProvider();
/** /**
* *
*/ */
List<DateModel> monthList = []; //list List<DateModel> monthList = new List(); //list
List<DateModel> weekList = []; //list List<DateModel> weekList = new List(); //list
PageController? monthController; //controller PageController monthController; //controller
PageController? weekController; //controller PageController weekController; //controller
CalendarController( CalendarController(
{CalendarSelectedMode selectMode = CalendarSelectedMode.singleSelect, {int selectMode = CalendarConstants.MODE_SINGLE_SELECT,
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,
@ -50,12 +48,9 @@ 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) {
@ -81,11 +76,10 @@ 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());
@ -94,13 +88,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,
@ -111,29 +105,18 @@ 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();
@ -166,13 +149,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;
@ -194,29 +177,22 @@ 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);
} }
// //
@ -224,11 +200,6 @@ 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;
@ -263,7 +234,7 @@ class CalendarController {
//item //item
void changeDefaultSelectedDateList(Set<DateModel> defaultSelectedDateList) { void changeDefaultSelectedDateList(Set<DateModel> defaultSelectedDateList) {
this.calendarConfiguration.defaultSelectedDateList = this.calendarConfiguration.defaultSelectedDateList =
defaultSelectedDateList as HashSet<DateModel?>?; defaultSelectedDateList;
this.calendarProvider.generation.value++; this.calendarProvider.generation.value++;
} }
@ -280,13 +251,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);
@ -301,11 +272,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;
} }
@ -321,13 +292,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);
@ -343,11 +314,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;
} }
@ -366,15 +337,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 {
@ -389,15 +360,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);
} }
} }
@ -409,7 +380,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();
@ -424,7 +395,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();
@ -440,30 +411,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();
@ -479,30 +450,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();
@ -513,16 +484,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;
} }
@ -531,8 +502,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;
} }
} }
@ -571,21 +542,17 @@ 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,17 +1,12 @@
library flutter_custom_calendar; library flutter_custom_calendar;
export 'controller.dart'; export 'package:flutter_custom_calendar/controller.dart';
export 'widget/calendar_view.dart'; export 'package:flutter_custom_calendar/widget/calendar_view.dart';
export 'widget/base_day_view.dart'; export 'package:flutter_custom_calendar/widget/base_day_view.dart';
export 'widget/base_week_bar.dart'; export 'package:flutter_custom_calendar/widget/base_week_bar.dart';
export 'constants/constants.dart'; export 'package:flutter_custom_calendar/constants/constants.dart';
export 'model/date_model.dart'; export 'package:flutter_custom_calendar/model/date_model.dart';
export 'widget/default_combine_day_view.dart'; export 'package:flutter_custom_calendar/widget/default_combine_day_view.dart';
export 'widget/default_custom_day_view.dart'; export 'package:flutter_custom_calendar/widget/default_custom_day_view.dart';
export 'widget/default_week_bar.dart'; export 'package:flutter_custom_calendar/widget/default_week_bar.dart';
export 'configuration.dart'; export 'package:flutter_custom_calendar/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<int> lunar = List(3);
// 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 (traditionFestival.isNotEmpty) {
return traditionFestival;
} else if (gregorianFestival.isNotEmpty) { } else if (gregorianFestival.isNotEmpty) {
return gregorianFestival; return gregorianFestival;
} else if (traditionFestival.isNotEmpty) {
return traditionFestival;
} 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,5 +1,4 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
/** /**
* 便 * 便
@ -15,9 +14,10 @@ class LogUtil {
* TAG: * TAG:
* message+ * message+
*/ */
static void log({required dynamic TAG, String message = ""}) { static void log(
if (_enableLog && kDebugMode) { {@required dynamic TAG , String message = ""}) {
debugPrint("flutter_custom_calendar------$TAG------>$message"); if (_enableLog) {
print("flutter_custom_calendar------$TAG------>$message");
} }
} }
} }

@ -1,6 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart'; import 'package:flutter_custom_calendar/utils/LogUtil.dart';
import 'LogUtil.dart';
/** /**
* *
@ -31,7 +30,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 ||
@ -51,7 +50,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;
@ -63,7 +62,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;
} }
@ -100,25 +99,23 @@ class DateUtil {
* ,1 * ,1
* @return the start diff with MonthView * @return the start diff with MonthView
*/ */
static int getIndexOfFirstDayInMonth(DateTime dateTime, {int offset = 0}) { static int getIndexOfFirstDayInMonth(DateTime dateTime) {
DateTime firstDayOfMonth = new DateTime(dateTime.year, dateTime.month, 1); DateTime firstDayOfMonth = new DateTime(dateTime.year, dateTime.month, 1);
int week = firstDayOfMonth.weekday + offset; int week = firstDayOfMonth.weekday;
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 = int mPreDiff = getIndexOfFirstDayInMonth(new DateTime(year, month));
getIndexOfFirstDayInMonth(new DateTime(year, month), offset: offset);
// //
int monthDayCount = getMonthDaysCount(year, month); int monthDayCount = getMonthDaysCount(year, month);
@ -127,7 +124,8 @@ 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;
@ -138,10 +136,6 @@ 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));
@ -161,21 +155,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);
@ -189,31 +183,32 @@ class DateUtil {
/** /**
* *
*/ */
static int getMonthViewLineCount(int year, int month, int offset) { static int getMonthViewLineCount(int year, int month) {
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: "getMonthViewLineCount:$year$month月:有$lineCount"); message:
"getMonthViewLineCount:$year$month月:有${((preIndex + monthDayCount) / 7).toInt() + 1}");
return lineCount; return ((preIndex + monthDayCount) / 7).toInt() + 1;
} }
/** /**
* 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}) {
int offset = 0}) { List<DateModel> items = List();
List<DateModel> items = [];
int weekDay = currentDate.weekday + offset; int weekDay = currentDate.weekday;
// //
DateTime firstDayOfWeek = currentDate.add(Duration(days: -weekDay)); DateTime firstDayOfWeek = currentDate.add(Duration(days: -weekDay));
@ -223,8 +218,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;
@ -237,7 +232,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,9 +1,11 @@
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart'; import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart';
import 'package:flutter_custom_calendar/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,
@ -461,14 +463,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情人节",
@ -506,7 +508,7 @@ class LunarUtil {
/** /**
* , * ,
*/ */
static final Map<int?, List<String?>> SPECIAL_FESTIVAL = new Map(); static final Map<int, List<String>> SPECIAL_FESTIVAL = new Map();
/** /**
* *
@ -756,8 +758,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));
@ -809,7 +811,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 = [0,0,0,0]; List<int> lunarInt = new List(4);
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;
@ -861,12 +863,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; y = y - (m / 10).toInt();
return (365 * y + return (365 * y +
y ~/ 4 - (y / 4).toInt() -
y ~/ 100 + (y / 100).toInt() +
y ~/ 400 + (y / 400).toInt() +
(m * 306 + 5) ~/ 10 + ((m * 306 + 5) / 10).toInt() +
(d - 1)); (d - 1));
} }
@ -878,15 +880,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;
} }
@ -902,11 +904,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];
} }
/** /**
@ -916,11 +918,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) {
@ -955,14 +957,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)) {
@ -997,15 +999,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;
} }
@ -1020,8 +1022,8 @@ class LunarUtil {
* @param year * @param year
* @return * @return
*/ */
static List<String?> getSpecialFestivals(int year) { static List<String> getSpecialFestivals(int year) {
List<String?> festivals = ['','','']; List<String> festivals = new List(3);
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,8 +3,14 @@ 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 = [
"春分", "春分",
"清明", "清明",
@ -32,17 +38,25 @@ 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,
@ -54,7 +68,9 @@ class SolarTermUtil {
0.00001 0.00001
]; ];
/// /**
*
*/
static final List<double> DTS = [ static final List<double> DTS = [
-4000, -4000,
108371.7, 108371.7,
@ -196,8 +212,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;
} }
@ -318,14 +334,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);
} }
/** /**
@ -2001,7 +2017,7 @@ class SolarTermUtil {
*/ */
static List<double> earCal(double jd) { static List<double> earCal(double jd) {
EnnT = jd / 365250; EnnT = jd / 365250;
List<double> llr = [0,0,0]; List<double> llr = new List(3);
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 +
@ -2042,16 +2058,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 = [0,0,0]; List<double> llr = new List(3);
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;
} }
@ -2074,8 +2090,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]));
} }
/** /**
@ -2123,13 +2139,10 @@ class SolarTermUtil {
* @return 24 * @return 24
*/ */
static List<String?> getSolarTerms(int year) { static List<String> getSolarTerms(int year) {
List<String?> solarTerms = []; List<String> solarTerms = new List(24);
for(int i=0;i<24;i++){ List<String> preOffset = getSolarTermsPreOffset(year - 1);
solarTerms.add(''); List<String> nextOffset = getSolarTermsNextOffset(year - 1);
}
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);
@ -2150,8 +2163,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 = ['','','']; List<String> solarTerms = new List(3);
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);
@ -2168,8 +2181,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 = ['','']; List<String> solarTerms = new List(2);
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);
@ -2188,21 +2201,21 @@ class Nutation {
/** /**
* *
*/ */
late double Lon; double Lon;
/** /**
* *
*/ */
late double Obl; double Obl;
} }
class Time { class Time {
late double year; double year;
late double month; double month;
late double day; double day;
late double hour; double hour;
late double minute; double minute;
late double second; double second;
String toString() { String toString() {
return doubleToString(year) + doubleToString(month) + doubleToString(day); return doubleToString(year) + doubleToString(month) + doubleToString(day);

@ -1,8 +1,6 @@
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
@ -20,7 +18,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,
@ -37,15 +35,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
@ -64,7 +62,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,17 +1,14 @@
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';
/** /**
* *
*/ */
@ -19,14 +16,14 @@ import 'month_view_pager.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;
@ -39,10 +36,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,
@ -102,12 +99,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;
late bool expand; bool expand;
late CalendarProvider calendarProvider; CalendarProvider calendarProvider;
List<Widget> widgets = []; List<Widget> widgets = [];
@ -119,15 +116,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());
@ -139,9 +136,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(() {
@ -151,12 +148,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);
} }
}); });
@ -166,19 +163,18 @@ 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);
widget.calendarController.calendarConfiguration.offset); double newHeight = itemHeight * (lineCount) +
double newHeight = itemHeight! * (lineCount) + calendarProvider.calendarConfiguration.verticalSpacing *
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;
@ -187,7 +183,7 @@ class CalendarContainerState extends State<CalendarContainer>
} }
}); });
itemHeight = calendarProvider.calendarConfiguration!.itemSize; itemHeight = calendarProvider.calendarConfiguration.itemSize;
totalHeight = calendarProvider.totalHeight; totalHeight = calendarProvider.totalHeight;
} }
@ -200,7 +196,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,
@ -208,7 +204,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,9 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart'; import 'package:flutter_custom_calendar/widget/base_day_view.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/style/style.dart'; import 'package:flutter_custom_calendar/style/style.dart';
import 'base_day_view.dart';
/** /**
* widgetitem * widgetitem
*/ */

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

@ -1,9 +1,8 @@
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';
///** ///**
// * // *
// */ // */
@ -40,7 +39,7 @@ import 'base_week_bar.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,8 +1,10 @@
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/flutter_custom_calendar.dart'; import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart'; import 'package:flutter_custom_calendar/utils/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';
@ -11,16 +13,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);
@ -31,37 +33,37 @@ class MonthView extends StatefulWidget {
class _MonthViewState extends State<MonthView> class _MonthViewState extends State<MonthView>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
List<DateModel>? items =[]; List<DateModel> items = List();
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( lineCount = DateUtil.getMonthViewLineCount(widget.year, widget.month);
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();
}); });
}); });
@ -71,10 +73,9 @@ 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(() {});
} }
@ -84,8 +85,7 @@ 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,65 +96,36 @@ 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 : items!.length, itemCount: items.isEmpty ? 0 : 7 * lineCount,
itemBuilder: (context, index) { itemBuilder: (context, index) {
DateModel dateModel = items![index]; DateModel dateModel = items[index];
// //
switch (configuration.selectMode) { if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) {
if (calendarProvider.selectedDateList.contains(dateModel)) {
/// dateModel.isSelected = true;
case CalendarSelectedMode.multiSelect: } else {
if (calendarProvider.selectedDateList!.contains(dateModel)) { dateModel.isSelected = false;
dateModel.isSelected = true; }
} else { } else {
dateModel.isSelected = false; if (calendarProvider.selectDateModel == dateModel) {
} dateModel.isSelected = true;
break; } else {
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(dateModel), key: ObjectKey(
clickCall: () { dateModel), //使objectKey1flutter2statefulElementstate
setState(() {});
// if (configuration.selectMode ==
// CalendarSelectedMode.mutltiStartToEndSelect)
///
},
//使objectKey1flutter2statefulElementstate
); );
}); });
} }
@ -167,60 +138,53 @@ class _MonthViewState extends State<MonthView>
* itemitem * itemitem
*/ */
class ItemContainer extends StatefulWidget { class ItemContainer extends StatefulWidget {
final DateModel? dateModel; final DateModel dateModel;
final GestureTapCallback? clickCall; const ItemContainer({
const ItemContainer({Key? key, this.dateModel, this.clickCall}) Key key,
: super(key: key); this.dateModel,
}) : 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;
late CalendarProvider calendarProvider; 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(bool v) { void refreshItem() {
/** /**
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 = v; dateModel.isSelected = !dateModel.isSelected;
// 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);
} }
} }
@ -239,121 +203,48 @@ class ItemContainerState extends State<ItemContainer> {
message: "GestureDetector onTap: $dateModel}"); message: "GestureDetector onTap: $dateModel}");
// //
if (!dateModel!.isInRange) { if (!dateModel.isInRange) {
// //
if (configuration!.selectMode == CalendarSelectedMode.multiSelect) { if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) {
configuration!.multiSelectOutOfRange(); configuration.multiSelectOutOfRange();
} }
return; return;
} }
calendarProvider.lastClickDateModel = dateModel; calendarProvider.lastClickDateModel = dateModel;
switch (configuration!.selectMode) { if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) {
// if (calendarProvider.selectedDateList.contains(dateModel)) {
case CalendarSelectedMode.multiSelect: calendarProvider.selectedDateList.remove(dateModel);
if (calendarProvider.selectedDateList!.contains(dateModel)) { } else {
calendarProvider.selectedDateList!.remove(dateModel); //
_notifiCationUnCalendarSelect(dateModel); if (calendarProvider.selectedDateList.length ==
} else { configuration.maxMultiSelectCount) {
// if (configuration.multiSelectOutOfSize != null) {
if (calendarProvider.selectedDateList!.length == configuration.multiSelectOutOfSize();
configuration!.maxMultiSelectCount) {
if (configuration!.multiSelectOutOfSize != null) {
configuration!.multiSelectOutOfSize!();
}
return;
} }
dateModel!.isSelected = !dateModel!.isSelected!; return;
calendarProvider.selectedDateList!.add(dateModel);
}
//
calendarProvider.selectDateModel = dateModel;
print('多选:${calendarProvider.selectedDateList.toString()}');
break;
///
case CalendarSelectedMode.singleSelect:
///
calendarProvider.selectedDateList!.forEach((element) {
element!.isSelected = false;
_notifiCationUnCalendarSelect(element);
});
calendarProvider.selectedDateList!.clear();
//item
if (calendarProvider.lastClickItemState != this) {
calendarProvider.lastClickItemState?.refreshItem(false);
calendarProvider.lastClickItemState = this;
} }
_notifiCationUnCalendarSelect(calendarProvider.selectDateModel); calendarProvider.selectedDateList.add(dateModel);
dateModel!.isSelected = true; }
calendarProvider.selectDateModel = dateModel; configuration.calendarSelect(dateModel);
_notifiCationCalendarSelect(dateModel);
setState(() {}); //
calendarProvider.selectDateModel = dateModel;
break; } else {
calendarProvider.selectDateModel = dateModel;
/// configuration.calendarSelect(dateModel);
case CalendarSelectedMode.mutltiStartToEndSelect:
if (calendarProvider.selectedDateList!.length == 0) { //item
calendarProvider.selectedDateList!.add(dateModel); if (calendarProvider.lastClickItemState != this) {
} else if (calendarProvider.selectedDateList!.length == 1) { calendarProvider.lastClickItemState?.refreshItem();
DateModel? d2 = calendarProvider.selectedDateList!.first; calendarProvider.lastClickItemState = this;
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(!this.dateModel!.isSelected!); refreshItem();
}, },
child: configuration!.dayWidgetBuilder!(dateModel!), child: configuration.dayWidgetBuilder(dateModel),
); );
} }

@ -1,14 +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/calendar_provider.dart';
import 'package:flutter_custom_calendar/configuration.dart'; import 'package:flutter_custom_calendar/configuration.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/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();
@ -16,7 +15,7 @@ class MonthViewPager extends StatefulWidget {
class _MonthViewPagerState extends State<MonthViewPager> class _MonthViewPagerState extends State<MonthViewPager>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
late CalendarProvider calendarProvider; CalendarProvider calendarProvider;
@override @override
void initState() { void initState() {
@ -63,39 +62,38 @@ 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,
); );
} }

@ -1,55 +0,0 @@
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/flutter_custom_calendar.dart'; import 'package:flutter_custom_calendar/constants/constants.dart';
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/date_util.dart'; import 'package:flutter_custom_calendar/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,33 +27,31 @@ class WeekView extends StatefulWidget {
} }
class _WeekViewState extends State<WeekView> { class _WeekViewState extends State<WeekView> {
late List<DateModel> items; 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(() {});
}); });
}); });
@ -64,7 +62,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}");
@ -76,39 +74,25 @@ class _WeekViewState extends State<WeekView> {
itemBuilder: (context, index) { itemBuilder: (context, index) {
DateModel dateModel = items[index]; DateModel dateModel = items[index];
// //
switch (configuration!.selectMode) { if (configuration.selectMode == CalendarConstants.MODE_MULTI_SELECT) {
case CalendarSelectedMode.multiSelect: if (calendarProvider.selectedDateList.contains(dateModel)) {
if (calendarProvider.selectedDateList!.contains(dateModel)) { dateModel.isSelected = true;
dateModel.isSelected = true; } else {
} else { dateModel.isSelected = false;
dateModel.isSelected = false; }
} } else {
break; if (calendarProvider.selectDateModel == dateModel) {
case CalendarSelectedMode.singleSelect: dateModel.isSelected = true;
if (calendarProvider.selectDateModel == dateModel) { } else {
dateModel.isSelected = true; dateModel.isSelected = false;
} 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,
clickCall: () { // configuration: configuration,
setState(() {}); // calendarProvider: calendarProvider,
}); );
}); });
} }
} }

@ -1,13 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/widget/week_view.dart'; import 'package:flutter_custom_calendar/calendar_provider.dart';
import 'package:provider/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/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/widget/week_view.dart';
import 'package:provider/provider.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; //
late CalendarProvider calendarProvider; 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,55 +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.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.6.1" version: "2.3.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.0.5"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.1.2"
clock: collection:
dependency: transitive dependency: transitive
description: description:
name: clock name: collection
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.14.11"
collection: convert:
dependency: transitive dependency: transitive
description: description:
name: collection name: convert
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.15.0" version: "2.1.1"
fake_async: crypto:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: crypto
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "2.1.3"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -60,41 +67,62 @@ 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.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10" version: "0.12.5"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0" version: "1.1.7"
nested: path:
dependency: transitive dependency: transitive
description: description:
name: nested name: path
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.0.0" version: "1.6.4"
path: pedantic:
dependency: transitive dependency: transitive
description: description:
name: path name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.0+1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0" version: "2.4.0"
provider: provider:
dependency: "direct main" dependency: "direct main"
description: description:
name: provider name: provider
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "6.0.3" version: "3.1.0+1"
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
@ -104,58 +132,64 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.1" version: "1.5.5"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.10.0" version: "1.9.3"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "2.0.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.0.5"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.1.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.3.0" version: "0.2.5"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0" version: "1.1.6"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.8"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "3.5.0"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.4.0 <3.0.0"
flutter: ">=1.16.0"

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

@ -1,9 +0,0 @@
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