├── example ├── linux │ ├── .gitignore │ ├── main.cc │ ├── flutter │ │ ├── generated_plugin_registrant.cc │ │ ├── generated_plugin_registrant.h │ │ ├── generated_plugins.cmake │ │ └── CMakeLists.txt │ ├── my_application.h │ ├── my_application.cc │ └── CMakeLists.txt ├── ios │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ └── .gitignore ├── macos │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Runner │ │ ├── Configs │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ ├── Warnings.xcconfig │ │ │ └── AppInfo.xcconfig │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app_icon_1024.png │ │ │ │ ├── app_icon_128.png │ │ │ │ ├── app_icon_16.png │ │ │ │ ├── app_icon_256.png │ │ │ │ ├── app_icon_32.png │ │ │ │ ├── app_icon_512.png │ │ │ │ ├── app_icon_64.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Release.entitlements │ │ ├── DebugProfile.entitlements │ │ ├── MainFlutterWindow.swift │ │ └── Info.plist │ ├── .gitignore │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── web │ ├── favicon.png │ ├── icons │ │ ├── Icon-192.png │ │ ├── Icon-512.png │ │ ├── Icon-maskable-192.png │ │ └── Icon-maskable-512.png │ ├── manifest.json │ └── index.html ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── windows │ ├── runner │ │ ├── resources │ │ │ └── app_icon.ico │ │ ├── resource.h │ │ ├── utils.h │ │ ├── runner.exe.manifest │ │ ├── flutter_window.h │ │ ├── CMakeLists.txt │ │ ├── main.cpp │ │ ├── utils.cpp │ │ ├── flutter_window.cpp │ │ ├── Runner.rc │ │ ├── win32_window.h │ │ └── win32_window.cpp │ ├── flutter │ │ ├── generated_plugin_registrant.cc │ │ ├── generated_plugin_registrant.h │ │ ├── generated_plugins.cmake │ │ └── CMakeLists.txt │ ├── .gitignore │ └── CMakeLists.txt ├── lib │ ├── custom_animation.dart │ ├── test.dart │ └── main.dart ├── README.md ├── .gitignore ├── test │ └── widget_test.dart ├── .metadata └── pubspec.yaml ├── test └── flutter_easyloading_test.dart ├── docs ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── assets │ ├── AssetManifest.json │ ├── fonts │ │ └── MaterialIcons-Regular.ttf │ ├── packages │ │ └── cupertino_icons │ │ │ └── assets │ │ │ └── CupertinoIcons.ttf │ └── FontManifest.json ├── manifest.json ├── index.html └── flutter_service_worker.js ├── images ├── gif01.gif ├── gif02.gif ├── gif03.gif ├── gif04.gif └── jetbrains.png ├── .github ├── ISSUE_TEMPLATE │ ├── feature.md │ └── bug.md └── workflows │ └── greetings.yml ├── .metadata ├── pubspec.yaml ├── LICENSE ├── lib ├── flutter_easyloading.dart └── src │ ├── animations │ ├── opacity_animation.dart │ ├── animation.dart │ ├── scale_animation.dart │ └── offset_animation.dart │ ├── widgets │ ├── overlay_entry.dart │ ├── loading.dart │ ├── progress.dart │ ├── indicator.dart │ └── container.dart │ ├── theme.dart │ └── easy_loading.dart ├── .gitignore ├── CHANGELOG.md ├── README-zh_CN.md └── README.md /example/linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /test/flutter_easyloading_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /docs/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/docs/favicon.png -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /images/gif01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/images/gif01.gif -------------------------------------------------------------------------------- /images/gif02.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/images/gif02.gif -------------------------------------------------------------------------------- /images/gif03.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/images/gif03.gif -------------------------------------------------------------------------------- /images/gif04.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/images/gif04.gif -------------------------------------------------------------------------------- /images/jetbrains.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/images/jetbrains.png -------------------------------------------------------------------------------- /docs/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/docs/icons/Icon-192.png -------------------------------------------------------------------------------- /docs/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/docs/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /docs/assets/AssetManifest.json: -------------------------------------------------------------------------------- 1 | {"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]} -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /docs/assets/fonts/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/docs/assets/fonts/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /example/windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /docs/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/docs/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nslogx/flutter_easyloading/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /docs/assets/FontManifest.json: -------------------------------------------------------------------------------- 1 | [{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.ttf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]}] -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | 9 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 10 | } 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest a new idea for Flutter EasyLoading. 4 | 5 | --- 6 | 7 | **Describe the Feature request** 8 | Please tell us the problem you are running into that led to you wanting 9 | a new feature. -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void fl_register_plugins(FlPluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /example/windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void RegisterPlugins(flutter::PluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 7 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 27321ebbad34b0a3fafe99fac037102196d655ff 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **Flutter/Dart info** 11 | please run `flutter doctor` then put it here. 12 | 13 | **Screenshots** 14 | If applicable, add screenshots to help explain your problem. 15 | -------------------------------------------------------------------------------- /example/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /example/windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_easyloading 2 | description: A clean and lightweight loading/toast widget for Flutter, Easy to use without context, Support iOS、Android and Web 3 | version: 3.0.5 4 | homepage: https://github.com/nslogx/flutter_easyloading 5 | 6 | environment: 7 | sdk: ">=2.12.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | flutter_spinkit: ^5.1.0 14 | 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | 19 | flutter: 20 | -------------------------------------------------------------------------------- /example/linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: [pull_request, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/first-interaction@v1 10 | with: 11 | repo-token: ${{ secrets.GITHUB_TOKEN }} 12 | issue-message: 'Thanks for taking the time to open an issue. I will have a look and answer as soon as possible.' 13 | pr-message: 'Thank you for opening an PR. I will review the PR and provide feedback as soon as possible.' 14 | -------------------------------------------------------------------------------- /example/windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/lib/custom_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 3 | 4 | class CustomAnimation extends EasyLoadingAnimation { 5 | CustomAnimation(); 6 | 7 | @override 8 | Widget buildWidget( 9 | Widget child, 10 | AnimationController controller, 11 | AlignmentGeometry alignment, 12 | ) { 13 | return Opacity( 14 | opacity: controller.value, 15 | child: RotationTransition( 16 | turns: controller, 17 | child: child, 18 | ), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /docs/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "minimal-ui", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "minimal-ui", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | -------------------------------------------------------------------------------- /example/windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /example/windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 nslogx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | example 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | example 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Disable Windows macros that collide with C++ standard library functions. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 25 | 26 | # Add dependency libraries and include directories. Add any application-specific 27 | # dependencies here. 28 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 29 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 30 | 31 | # Run the Flutter tool portions of the build. This must not be removed. 32 | add_dependencies(${BINARY_NAME} flutter_assemble) 33 | -------------------------------------------------------------------------------- /lib/flutter_easyloading.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | library flutter_easyloading; 24 | 25 | export 'src/easy_loading.dart'; 26 | export 'src/widgets/loading.dart'; 27 | export 'src/animations/animation.dart'; 28 | -------------------------------------------------------------------------------- /example/windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.CreateAndShow(L"example", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /docs/flutter_service_worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const CACHE_NAME = 'flutter-app-cache'; 3 | const RESOURCES = { 4 | "index.html": "926cd8008bef60a4e735ba8d18fbac9c", 5 | "/": "926cd8008bef60a4e735ba8d18fbac9c", 6 | "main.dart.js": "03c0c72e6e3d731e6989ecc789bba9e5", 7 | "favicon.png": "5dcef449791fa27946b3d35ad8803796", 8 | "icons/Icon-192.png": "ac9a721a12bbc803b44f645561ecb1e1", 9 | "icons/Icon-512.png": "96e752610906ba2a93c65f8abe1645f1", 10 | "manifest.json": "00e0b69b49487ce4f9ff0c5fac8fda49", 11 | "assets/LICENSE": "f635997a7f9a0d70e5838c41b7c1b4e5", 12 | "assets/AssetManifest.json": "2efbb41d7877d10aac9d091f58ccd7b9", 13 | "assets/FontManifest.json": "01700ba55b08a6141f33e168c4a6c22f", 14 | "assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "115e937bb829a890521f72d2e664b632", 15 | "assets/fonts/MaterialIcons-Regular.ttf": "56d3ffdef7a25659eab6a68a3fbfaf16" 16 | }; 17 | 18 | self.addEventListener('activate', function (event) { 19 | event.waitUntil( 20 | caches.keys().then(function (cacheName) { 21 | return caches.delete(cacheName); 22 | }).then(function (_) { 23 | return caches.open(CACHE_NAME); 24 | }).then(function (cache) { 25 | return cache.addAll(Object.keys(RESOURCES)); 26 | }) 27 | ); 28 | }); 29 | 30 | self.addEventListener('fetch', function (event) { 31 | event.respondWith( 32 | caches.match(event.request) 33 | .then(function (response) { 34 | if (response) { 35 | return response; 36 | } 37 | return fetch(event.request); 38 | }) 39 | ); 40 | }); 41 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/src/animations/opacity_animation.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/widgets.dart'; 24 | 25 | import 'animation.dart'; 26 | 27 | class OpacityAnimation extends EasyLoadingAnimation { 28 | OpacityAnimation(); 29 | 30 | @override 31 | Widget buildWidget( 32 | Widget child, 33 | AnimationController controller, 34 | AlignmentGeometry alignment, 35 | ) { 36 | return Opacity( 37 | opacity: controller.value, 38 | child: child, 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/src/animations/animation.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/widgets.dart'; 24 | 25 | abstract class EasyLoadingAnimation { 26 | EasyLoadingAnimation(); 27 | 28 | Widget call( 29 | Widget child, 30 | AnimationController controller, 31 | AlignmentGeometry alignment, 32 | ) { 33 | return buildWidget( 34 | child, 35 | controller, 36 | alignment, 37 | ); 38 | } 39 | 40 | Widget buildWidget( 41 | Widget child, 42 | AnimationController controller, 43 | AlignmentGeometry alignment, 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /lib/src/animations/scale_animation.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/widgets.dart'; 24 | 25 | import 'animation.dart'; 26 | 27 | class ScaleAnimation extends EasyLoadingAnimation { 28 | ScaleAnimation(); 29 | 30 | @override 31 | Widget buildWidget( 32 | Widget child, 33 | AnimationController controller, 34 | AlignmentGeometry alignment, 35 | ) { 36 | return Opacity( 37 | opacity: controller.value, 38 | child: ScaleTransition( 39 | scale: controller, 40 | child: child, 41 | ), 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 17 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 18 | - platform: android 19 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 20 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 21 | - platform: ios 22 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 23 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 24 | - platform: linux 25 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 26 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 27 | - platform: macos 28 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 29 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 30 | - platform: web 31 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 32 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 33 | - platform: windows 34 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 35 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /example/windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | std::string utf8_string; 52 | if (target_length == 0 || target_length > utf8_string.max_size()) { 53 | return utf8_string; 54 | } 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 76 | 77 | 78 | # add some ignore 79 | .vscode 80 | pubspec.lock 81 | 82 | .vscode/launch.json 83 | example/pubspec.lock -------------------------------------------------------------------------------- /example/lib/test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 5 | 6 | class TestPage extends StatefulWidget { 7 | @override 8 | _TestPageState createState() => _TestPageState(); 9 | } 10 | 11 | class _TestPageState extends State { 12 | @override 13 | void initState() { 14 | super.initState(); 15 | // EasyLoading.dismiss(); 16 | EasyLoading.showSuccess('Use in initState'); 17 | EasyLoading.addStatusCallback(statusCallback); 18 | } 19 | 20 | @override 21 | void deactivate() { 22 | EasyLoading.dismiss(); 23 | EasyLoading.removeCallback(statusCallback); 24 | super.deactivate(); 25 | } 26 | 27 | void statusCallback(EasyLoadingStatus status) { 28 | print('Test EasyLoading Status $status'); 29 | } 30 | 31 | void loadData() async { 32 | try { 33 | await EasyLoading.show(); 34 | HttpClient client = HttpClient(); 35 | HttpClientRequest request = 36 | await client.getUrl(Uri.parse('https://github.com')); 37 | HttpClientResponse response = await request.close(); 38 | print(response); 39 | await EasyLoading.dismiss(); 40 | } catch (e) { 41 | await EasyLoading.showError(e.toString()); 42 | print(e); 43 | } 44 | } 45 | 46 | @override 47 | Widget build(BuildContext context) { 48 | return Scaffold( 49 | appBar: AppBar( 50 | title: Text('Test Page'), 51 | ), 52 | body: Center( 53 | child: TextButton( 54 | child: Text('loadData'), 55 | onPressed: () { 56 | EasyLoading.show(status: '加载中...'); 57 | // loadData(); 58 | // await Future.delayed(Duration(seconds: 2)); 59 | // EasyLoading.show(status: 'loading...'); 60 | // await Future.delayed(Duration(seconds: 5)); 61 | // EasyLoading.dismiss(); 62 | }, 63 | ), 64 | ), 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/src/widgets/overlay_entry.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/material.dart'; 24 | import 'package:flutter/scheduler.dart'; 25 | 26 | //https://docs.flutter.dev/development/tools/sdk/release-notes/release-notes-3.0.0 27 | T? _ambiguate(T? value) => value; 28 | 29 | class EasyLoadingOverlayEntry extends OverlayEntry { 30 | final WidgetBuilder builder; 31 | 32 | EasyLoadingOverlayEntry({ 33 | required this.builder, 34 | }) : super(builder: builder); 35 | 36 | @override 37 | void markNeedsBuild() { 38 | if (_ambiguate(SchedulerBinding.instance)!.schedulerPhase == 39 | SchedulerPhase.persistentCallbacks) { 40 | _ambiguate(SchedulerBinding.instance)!.addPostFrameCallback((_) { 41 | super.markNeedsBuild(); 42 | }); 43 | } else { 44 | super.markNeedsBuild(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /example/windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | return true; 30 | } 31 | 32 | void FlutterWindow::OnDestroy() { 33 | if (flutter_controller_) { 34 | flutter_controller_ = nullptr; 35 | } 36 | 37 | Win32Window::OnDestroy(); 38 | } 39 | 40 | LRESULT 41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 42 | WPARAM const wparam, 43 | LPARAM const lparam) noexcept { 44 | // Give Flutter, including plugins, an opportunity to handle window messages. 45 | if (flutter_controller_) { 46 | std::optional result = 47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 48 | lparam); 49 | if (result) { 50 | return *result; 51 | } 52 | } 53 | 54 | switch (message) { 55 | case WM_FONTCHANGE: 56 | flutter_controller_->engine()->ReloadSystemFonts(); 57 | break; 58 | } 59 | 60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 61 | } 62 | -------------------------------------------------------------------------------- /lib/src/animations/offset_animation.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/widgets.dart'; 24 | 25 | import 'animation.dart'; 26 | 27 | class OffsetAnimation extends EasyLoadingAnimation { 28 | OffsetAnimation(); 29 | 30 | @override 31 | Widget buildWidget( 32 | Widget child, 33 | AnimationController controller, 34 | AlignmentGeometry alignment, 35 | ) { 36 | Offset _begin = alignment == AlignmentDirectional.topCenter 37 | ? Offset(0, -1) 38 | : alignment == AlignmentDirectional.bottomCenter 39 | ? Offset(0, 1) 40 | : Offset(0, 0); 41 | Animation _animation = Tween( 42 | begin: _begin, 43 | end: Offset(0, 0), 44 | ).animate(controller); 45 | return Opacity( 46 | opacity: controller.value, 47 | child: SlideTransition( 48 | position: _animation, 49 | child: child, 50 | ), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.example.example" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 50 | minSdkVersion flutter.minSdkVersion 51 | targetSdkVersion flutter.targetSdkVersion 52 | versionCode flutterVersionCode.toInteger() 53 | versionName flutterVersionName 54 | } 55 | 56 | buildTypes { 57 | release { 58 | // TODO: Add your own signing config for the release build. 59 | // Signing with the debug keys for now, so `flutter run --release` works. 60 | signingConfig signingConfigs.debug 61 | } 62 | } 63 | } 64 | 65 | flutter { 66 | source '../..' 67 | } 68 | 69 | dependencies { 70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 71 | } 72 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/src/widgets/loading.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/material.dart'; 24 | 25 | import '../easy_loading.dart'; 26 | import './overlay_entry.dart'; 27 | 28 | class FlutterEasyLoading extends StatefulWidget { 29 | final Widget? child; 30 | 31 | const FlutterEasyLoading({ 32 | Key? key, 33 | required this.child, 34 | }) : assert(child != null), 35 | super(key: key); 36 | 37 | @override 38 | _FlutterEasyLoadingState createState() => _FlutterEasyLoadingState(); 39 | } 40 | 41 | class _FlutterEasyLoadingState extends State { 42 | late EasyLoadingOverlayEntry _overlayEntry; 43 | 44 | @override 45 | void initState() { 46 | super.initState(); 47 | _overlayEntry = EasyLoadingOverlayEntry( 48 | builder: (BuildContext context) => EasyLoading.instance.w ?? Container(), 49 | ); 50 | EasyLoading.instance.overlayEntry = _overlayEntry; 51 | } 52 | 53 | @override 54 | Widget build(BuildContext context) { 55 | return Material( 56 | child: Overlay( 57 | initialEntries: [ 58 | EasyLoadingOverlayEntry( 59 | builder: (BuildContext context) { 60 | if (widget.child != null) { 61 | return widget.child!; 62 | } else { 63 | return Container(); 64 | } 65 | }, 66 | ), 67 | _overlayEntry, 68 | ], 69 | ), 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [3.0.5] - 2022.05.23 2 | 3 | * 🎉 It's support flutter 3.0 and previous version now 4 | * fixed [#169](https://github.com/nslogx/flutter_easyloading/issues/169) 5 | 6 | ## [3.0.3] - 2021.08.31 7 | 8 | * fixed [#126](https://github.com/nslogx/flutter_easyloading/issues/126) 9 | ## [3.0.2] - 2021.08.31 10 | 11 | * fixed [#125](https://github.com/nslogx/flutter_easyloading/issues/125) 12 | 13 | ## [3.0.1] - 2021.08.28 14 | 15 | * fixed [#120](https://github.com/nslogx/flutter_easyloading/issues/120) 16 | 17 | ## [3.0.0] - 2021.03.12 18 | 19 | * 🎉 It's support Null Safety now 20 | 21 | ## [2.2.2] - 2020.12.28 22 | 23 | * fixed [#77](https://github.com/nslogx/flutter_easyloading/issues/77) 24 | 25 | ## [2.2.1] - 2020.11.30 26 | 27 | * fixed bugs 28 | ## [2.2.0] - 2020.11.19 29 | 30 | * add init method 31 | 32 | ## [2.1.3] - 2020.11.13 33 | 34 | * fixed [#64](https://github.com/nslogx/flutter_easyloading/issues/64) 35 | 36 | ## [2.1.2] - 2020.11.12 37 | 38 | * fixed [#63](https://github.com/nslogx/flutter_easyloading/issues/63) 39 | 40 | ## [2.1.1] - 2020.11.11 41 | 42 | * fixed bugs 43 | 44 | ## [2.1.0] - 2020.11.11 45 | 46 | * add loading status callback 47 | * add dismissOnTap option [#59](https://github.com/nslogx/flutter_easyloading/issues/59) 48 | * fixed [#61](https://github.com/nslogx/flutter_easyloading/issues/61) 49 | * fixed bugs 50 | 51 | ## [2.0.1] - 2020.11.06 52 | 53 | * fixed [#58](https://github.com/nslogx/flutter_easyloading/issues/58) 54 | 55 | ## [2.0.0] - 2020.09.28 56 | 57 | * add custom animation style 58 | * add toast postion option [#14](https://github.com/nslogx/flutter_easyloading/issues/14) [#49](https://github.com/nslogx/flutter_easyloading/issues/49) 59 | * fixed bugs 60 | 61 | ## [1.3.0] - 2020.09.24 62 | 63 | * fixed bugs 64 | 65 | ## [1.2.1] - 2020.09.22 66 | 67 | * add indicatorWidget option [#45](https://github.com/nslogx/flutter_easyloading/issues/45) 68 | 69 | ## [1.2.0] - 2020.09.16 70 | 71 | * add textStyle option [#34](https://github.com/nslogx/flutter_easyloading/issues/34) 72 | * fixed bugs 73 | 74 | ## [1.1.4] - 2020.03.23 75 | 76 | * add lineWidth option [#9](https://github.com/nslogx/flutter_easyloading/issues/9) 77 | 78 | ## [1.1.3] - 2020.03.19 79 | 80 | * fixed [#8](https://github.com/nslogx/flutter_easyloading/issues/8) 81 | 82 | ## [1.1.2] - 2020.03.16 83 | 84 | * fixed [#7](https://github.com/nslogx/flutter_easyloading/issues/7) 85 | * optimize code style 86 | 87 | ## [1.1.1] - 2020.02.28 88 | 89 | * add showToast 90 | 91 | ## [1.0.1] - 2019.12.26 92 | 93 | * fixed bugs 94 | 95 | ## [1.0.0] - 2019.12.26 96 | 97 | * support custom style 98 | * relased v1.0.0 99 | * fixed bugs 100 | 101 | ## [0.0.3] - 2019.12.25 102 | 103 | * fixed bugs 104 | 105 | ## [0.0.2] - 2019.12.24 106 | 107 | * add indicatorType 108 | 109 | ## [0.0.1] - 2019.12.23 110 | 111 | * init 112 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.12.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | flutter_easyloading: ^3.0.0 24 | 25 | # The following adds the Cupertino Icons font to your application. 26 | # Use with the CupertinoIcons class for iOS style icons. 27 | cupertino_icons: ^0.1.2 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | # For information on the generic Dart part of this file, see the 34 | # following page: https://dart.dev/tools/pub/pubspec 35 | 36 | # The following section is specific to Flutter. 37 | flutter: 38 | # The following line ensures that the Material Icons font is 39 | # included with your application, so that you can use the icons in 40 | # the material Icons class. 41 | uses-material-design: true 42 | # To add assets to your application, add an assets section, like this: 43 | # assets: 44 | # - images/a_dot_burr.jpeg 45 | # - images/a_dot_ham.jpeg 46 | # An image asset can refer to one or more resolution-specific "variants", see 47 | # https://flutter.dev/assets-and-images/#resolution-aware. 48 | # For details regarding adding assets from package dependencies, see 49 | # https://flutter.dev/assets-and-images/#from-packages 50 | # To add custom fonts to your application, add a fonts section here, 51 | # in this "flutter" section. Each entry in this list should have a 52 | # "family" key with the font family name, and a "fonts" key with a 53 | # list giving the asset and other descriptors for the font. For 54 | # example: 55 | # fonts: 56 | # - family: Schyler 57 | # fonts: 58 | # - asset: fonts/Schyler-Regular.ttf 59 | # - asset: fonts/Schyler-Italic.ttf 60 | # style: italic 61 | # - family: Trajan Pro 62 | # fonts: 63 | # - asset: fonts/TrajanPro.ttf 64 | # - asset: fonts/TrajanPro_Bold.ttf 65 | # weight: 700 66 | # 67 | # For details regarding fonts from package dependencies, 68 | # see https://flutter.dev/custom-fonts/#from-packages 69 | -------------------------------------------------------------------------------- /example/linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.10) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | 12 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 13 | # which isn't available in 3.10. 14 | function(list_prepend LIST_NAME PREFIX) 15 | set(NEW_LIST "") 16 | foreach(element ${${LIST_NAME}}) 17 | list(APPEND NEW_LIST "${PREFIX}${element}") 18 | endforeach(element) 19 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 20 | endfunction() 21 | 22 | # === Flutter Library === 23 | # System-level dependencies. 24 | find_package(PkgConfig REQUIRED) 25 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 26 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 27 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 28 | 29 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 30 | 31 | # Published to parent scope for install step. 32 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 33 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 34 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 35 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 36 | 37 | list(APPEND FLUTTER_LIBRARY_HEADERS 38 | "fl_basic_message_channel.h" 39 | "fl_binary_codec.h" 40 | "fl_binary_messenger.h" 41 | "fl_dart_project.h" 42 | "fl_engine.h" 43 | "fl_json_message_codec.h" 44 | "fl_json_method_codec.h" 45 | "fl_message_codec.h" 46 | "fl_method_call.h" 47 | "fl_method_channel.h" 48 | "fl_method_codec.h" 49 | "fl_method_response.h" 50 | "fl_plugin_registrar.h" 51 | "fl_plugin_registry.h" 52 | "fl_standard_message_codec.h" 53 | "fl_standard_method_codec.h" 54 | "fl_string_codec.h" 55 | "fl_value.h" 56 | "fl_view.h" 57 | "flutter_linux.h" 58 | ) 59 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 60 | add_library(flutter INTERFACE) 61 | target_include_directories(flutter INTERFACE 62 | "${EPHEMERAL_DIR}" 63 | ) 64 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 65 | target_link_libraries(flutter INTERFACE 66 | PkgConfig::GTK 67 | PkgConfig::GLIB 68 | PkgConfig::GIO 69 | ) 70 | add_dependencies(flutter flutter_assemble) 71 | 72 | # === Flutter tool backend === 73 | # _phony_ is a non-existent file to force this command to run every time, 74 | # since currently there's no way to get a full input/output list from the 75 | # flutter tool. 76 | add_custom_command( 77 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 78 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 79 | COMMAND ${CMAKE_COMMAND} -E env 80 | ${FLUTTER_TOOL_ENVIRONMENT} 81 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 82 | ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} 83 | VERBATIM 84 | ) 85 | add_custom_target(flutter_assemble DEPENDS 86 | "${FLUTTER_LIBRARY}" 87 | ${FLUTTER_LIBRARY_HEADERS} 88 | ) 89 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #ifdef FLUTTER_BUILD_NUMBER 64 | #define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0 67 | #endif 68 | 69 | #ifdef FLUTTER_BUILD_NAME 70 | #define VERSION_AS_STRING #FLUTTER_BUILD_NAME 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "com.example" "\0" 93 | VALUE "FileDescription", "example" "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "example" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "example.exe" "\0" 98 | VALUE "ProductName", "example" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /example/windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_WIN32_WINDOW_H_ 2 | #define RUNNER_WIN32_WINDOW_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 11 | // inherited from by classes that wish to specialize with custom 12 | // rendering and input handling 13 | class Win32Window { 14 | public: 15 | struct Point { 16 | unsigned int x; 17 | unsigned int y; 18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 19 | }; 20 | 21 | struct Size { 22 | unsigned int width; 23 | unsigned int height; 24 | Size(unsigned int width, unsigned int height) 25 | : width(width), height(height) {} 26 | }; 27 | 28 | Win32Window(); 29 | virtual ~Win32Window(); 30 | 31 | // Creates and shows a win32 window with |title| and position and size using 32 | // |origin| and |size|. New windows are created on the default monitor. Window 33 | // sizes are specified to the OS in physical pixels, hence to ensure a 34 | // consistent size to will treat the width height passed in to this function 35 | // as logical pixels and scale to appropriate for the default monitor. Returns 36 | // true if the window was created successfully. 37 | bool CreateAndShow(const std::wstring& title, 38 | const Point& origin, 39 | const Size& size); 40 | 41 | // Release OS resources associated with window. 42 | void Destroy(); 43 | 44 | // Inserts |content| into the window tree. 45 | void SetChildContent(HWND content); 46 | 47 | // Returns the backing Window handle to enable clients to set icon and other 48 | // window properties. Returns nullptr if the window has been destroyed. 49 | HWND GetHandle(); 50 | 51 | // If true, closing this window will quit the application. 52 | void SetQuitOnClose(bool quit_on_close); 53 | 54 | // Return a RECT representing the bounds of the current client area. 55 | RECT GetClientArea(); 56 | 57 | protected: 58 | // Processes and route salient window messages for mouse handling, 59 | // size change and DPI. Delegates handling of these to member overloads that 60 | // inheriting classes can handle. 61 | virtual LRESULT MessageHandler(HWND window, 62 | UINT const message, 63 | WPARAM const wparam, 64 | LPARAM const lparam) noexcept; 65 | 66 | // Called when CreateAndShow is called, allowing subclass window-related 67 | // setup. Subclasses should return false if setup fails. 68 | virtual bool OnCreate(); 69 | 70 | // Called when Destroy is called. 71 | virtual void OnDestroy(); 72 | 73 | private: 74 | friend class WindowClassRegistrar; 75 | 76 | // OS callback called by message pump. Handles the WM_NCCREATE message which 77 | // is passed when the non-client area is being created and enables automatic 78 | // non-client DPI scaling so that the non-client area automatically 79 | // responsponds to changes in DPI. All other messages are handled by 80 | // MessageHandler. 81 | static LRESULT CALLBACK WndProc(HWND const window, 82 | UINT const message, 83 | WPARAM const wparam, 84 | LPARAM const lparam) noexcept; 85 | 86 | // Retrieves a class instance pointer for |window| 87 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 88 | 89 | bool quit_on_close_ = false; 90 | 91 | // window handle for top level window. 92 | HWND window_handle_ = nullptr; 93 | 94 | // window handle for hosted content. 95 | HWND child_content_ = nullptr; 96 | }; 97 | 98 | #endif // RUNNER_WIN32_WINDOW_H_ 99 | -------------------------------------------------------------------------------- /example/windows/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.14) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") 12 | 13 | # === Flutter Library === 14 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") 15 | 16 | # Published to parent scope for install step. 17 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 18 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 19 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 20 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) 21 | 22 | list(APPEND FLUTTER_LIBRARY_HEADERS 23 | "flutter_export.h" 24 | "flutter_windows.h" 25 | "flutter_messenger.h" 26 | "flutter_plugin_registrar.h" 27 | "flutter_texture_registrar.h" 28 | ) 29 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") 30 | add_library(flutter INTERFACE) 31 | target_include_directories(flutter INTERFACE 32 | "${EPHEMERAL_DIR}" 33 | ) 34 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") 35 | add_dependencies(flutter flutter_assemble) 36 | 37 | # === Wrapper === 38 | list(APPEND CPP_WRAPPER_SOURCES_CORE 39 | "core_implementations.cc" 40 | "standard_codec.cc" 41 | ) 42 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") 43 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN 44 | "plugin_registrar.cc" 45 | ) 46 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") 47 | list(APPEND CPP_WRAPPER_SOURCES_APP 48 | "flutter_engine.cc" 49 | "flutter_view_controller.cc" 50 | ) 51 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") 52 | 53 | # Wrapper sources needed for a plugin. 54 | add_library(flutter_wrapper_plugin STATIC 55 | ${CPP_WRAPPER_SOURCES_CORE} 56 | ${CPP_WRAPPER_SOURCES_PLUGIN} 57 | ) 58 | apply_standard_settings(flutter_wrapper_plugin) 59 | set_target_properties(flutter_wrapper_plugin PROPERTIES 60 | POSITION_INDEPENDENT_CODE ON) 61 | set_target_properties(flutter_wrapper_plugin PROPERTIES 62 | CXX_VISIBILITY_PRESET hidden) 63 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) 64 | target_include_directories(flutter_wrapper_plugin PUBLIC 65 | "${WRAPPER_ROOT}/include" 66 | ) 67 | add_dependencies(flutter_wrapper_plugin flutter_assemble) 68 | 69 | # Wrapper sources needed for the runner. 70 | add_library(flutter_wrapper_app STATIC 71 | ${CPP_WRAPPER_SOURCES_CORE} 72 | ${CPP_WRAPPER_SOURCES_APP} 73 | ) 74 | apply_standard_settings(flutter_wrapper_app) 75 | target_link_libraries(flutter_wrapper_app PUBLIC flutter) 76 | target_include_directories(flutter_wrapper_app PUBLIC 77 | "${WRAPPER_ROOT}/include" 78 | ) 79 | add_dependencies(flutter_wrapper_app flutter_assemble) 80 | 81 | # === Flutter tool backend === 82 | # _phony_ is a non-existent file to force this command to run every time, 83 | # since currently there's no way to get a full input/output list from the 84 | # flutter tool. 85 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") 86 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) 87 | add_custom_command( 88 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 89 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} 90 | ${CPP_WRAPPER_SOURCES_APP} 91 | ${PHONY_OUTPUT} 92 | COMMAND ${CMAKE_COMMAND} -E env 93 | ${FLUTTER_TOOL_ENVIRONMENT} 94 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" 95 | windows-x64 $ 96 | VERBATIM 97 | ) 98 | add_custom_target(flutter_assemble DEPENDS 99 | "${FLUTTER_LIBRARY}" 100 | ${FLUTTER_LIBRARY_HEADERS} 101 | ${CPP_WRAPPER_SOURCES_CORE} 102 | ${CPP_WRAPPER_SOURCES_PLUGIN} 103 | ${CPP_WRAPPER_SOURCES_APP} 104 | ) 105 | -------------------------------------------------------------------------------- /example/linux/my_application.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | #include 4 | #ifdef GDK_WINDOWING_X11 5 | #include 6 | #endif 7 | 8 | #include "flutter/generated_plugin_registrant.h" 9 | 10 | struct _MyApplication { 11 | GtkApplication parent_instance; 12 | char** dart_entrypoint_arguments; 13 | }; 14 | 15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) 16 | 17 | // Implements GApplication::activate. 18 | static void my_application_activate(GApplication* application) { 19 | MyApplication* self = MY_APPLICATION(application); 20 | GtkWindow* window = 21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); 22 | 23 | // Use a header bar when running in GNOME as this is the common style used 24 | // by applications and is the setup most users will be using (e.g. Ubuntu 25 | // desktop). 26 | // If running on X and not using GNOME then just use a traditional title bar 27 | // in case the window manager does more exotic layout, e.g. tiling. 28 | // If running on Wayland assume the header bar will work (may need changing 29 | // if future cases occur). 30 | gboolean use_header_bar = TRUE; 31 | #ifdef GDK_WINDOWING_X11 32 | GdkScreen* screen = gtk_window_get_screen(window); 33 | if (GDK_IS_X11_SCREEN(screen)) { 34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); 35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) { 36 | use_header_bar = FALSE; 37 | } 38 | } 39 | #endif 40 | if (use_header_bar) { 41 | GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); 42 | gtk_widget_show(GTK_WIDGET(header_bar)); 43 | gtk_header_bar_set_title(header_bar, "example"); 44 | gtk_header_bar_set_show_close_button(header_bar, TRUE); 45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); 46 | } else { 47 | gtk_window_set_title(window, "example"); 48 | } 49 | 50 | gtk_window_set_default_size(window, 1280, 720); 51 | gtk_widget_show(GTK_WIDGET(window)); 52 | 53 | g_autoptr(FlDartProject) project = fl_dart_project_new(); 54 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); 55 | 56 | FlView* view = fl_view_new(project); 57 | gtk_widget_show(GTK_WIDGET(view)); 58 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); 59 | 60 | fl_register_plugins(FL_PLUGIN_REGISTRY(view)); 61 | 62 | gtk_widget_grab_focus(GTK_WIDGET(view)); 63 | } 64 | 65 | // Implements GApplication::local_command_line. 66 | static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { 67 | MyApplication* self = MY_APPLICATION(application); 68 | // Strip out the first argument as it is the binary name. 69 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); 70 | 71 | g_autoptr(GError) error = nullptr; 72 | if (!g_application_register(application, nullptr, &error)) { 73 | g_warning("Failed to register: %s", error->message); 74 | *exit_status = 1; 75 | return TRUE; 76 | } 77 | 78 | g_application_activate(application); 79 | *exit_status = 0; 80 | 81 | return TRUE; 82 | } 83 | 84 | // Implements GObject::dispose. 85 | static void my_application_dispose(GObject* object) { 86 | MyApplication* self = MY_APPLICATION(object); 87 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); 88 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object); 89 | } 90 | 91 | static void my_application_class_init(MyApplicationClass* klass) { 92 | G_APPLICATION_CLASS(klass)->activate = my_application_activate; 93 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; 94 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose; 95 | } 96 | 97 | static void my_application_init(MyApplication* self) {} 98 | 99 | MyApplication* my_application_new() { 100 | return MY_APPLICATION(g_object_new(my_application_get_type(), 101 | "application-id", APPLICATION_ID, 102 | "flags", G_APPLICATION_NON_UNIQUE, 103 | nullptr)); 104 | } 105 | -------------------------------------------------------------------------------- /lib/src/widgets/progress.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'dart:math' as math; 24 | 25 | import 'package:flutter/material.dart'; 26 | 27 | import '../theme.dart'; 28 | 29 | class EasyLoadingProgress extends StatefulWidget { 30 | final double value; 31 | 32 | const EasyLoadingProgress({ 33 | Key? key, 34 | required this.value, 35 | }) : super(key: key); 36 | 37 | @override 38 | EasyLoadingProgressState createState() => EasyLoadingProgressState(); 39 | } 40 | 41 | class EasyLoadingProgressState extends State { 42 | /// value of progress, should be 0.0~1.0. 43 | double _value = 0; 44 | 45 | @override 46 | void initState() { 47 | super.initState(); 48 | } 49 | 50 | @override 51 | void dispose() { 52 | super.dispose(); 53 | } 54 | 55 | void updateProgress(double value) { 56 | setState(() { 57 | _value = value; 58 | }); 59 | } 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return SizedBox( 64 | width: EasyLoadingTheme.indicatorSize, 65 | height: EasyLoadingTheme.indicatorSize, 66 | child: _CircleProgress( 67 | value: _value, 68 | color: EasyLoadingTheme.progressColor, 69 | width: EasyLoadingTheme.progressWidth, 70 | ), 71 | ); 72 | } 73 | } 74 | 75 | class _CircleProgress extends ProgressIndicator { 76 | final double value; 77 | final double width; 78 | final Color color; 79 | 80 | _CircleProgress({ 81 | required this.value, 82 | required this.width, 83 | required this.color, 84 | }); 85 | 86 | @override 87 | __CircleProgressState createState() => __CircleProgressState(); 88 | } 89 | 90 | class __CircleProgressState extends State<_CircleProgress> { 91 | @override 92 | void initState() { 93 | super.initState(); 94 | } 95 | 96 | @override 97 | void dispose() { 98 | super.dispose(); 99 | } 100 | 101 | @override 102 | Widget build(BuildContext context) { 103 | return CustomPaint( 104 | painter: _CirclePainter( 105 | color: widget.color, 106 | value: widget.value, 107 | width: widget.width, 108 | ), 109 | ); 110 | } 111 | } 112 | 113 | class _CirclePainter extends CustomPainter { 114 | final Color color; 115 | final double value; 116 | final double width; 117 | 118 | _CirclePainter({ 119 | required this.color, 120 | required this.value, 121 | required this.width, 122 | }); 123 | 124 | @override 125 | void paint(Canvas canvas, Size size) { 126 | final paint = Paint() 127 | ..color = color 128 | ..strokeWidth = width 129 | ..style = PaintingStyle.stroke 130 | ..strokeCap = StrokeCap.round; 131 | canvas.drawArc( 132 | Offset.zero & size, 133 | -math.pi / 2, 134 | math.pi * 2 * value, 135 | false, 136 | paint, 137 | ); 138 | } 139 | 140 | @override 141 | bool shouldRepaint(_CirclePainter oldDelegate) => value != oldDelegate.value; 142 | } 143 | -------------------------------------------------------------------------------- /example/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project-level configuration. 2 | cmake_minimum_required(VERSION 3.14) 3 | project(example LANGUAGES CXX) 4 | 5 | # The name of the executable created for the application. Change this to change 6 | # the on-disk name of your application. 7 | set(BINARY_NAME "example") 8 | 9 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent 10 | # versions of CMake. 11 | cmake_policy(SET CMP0063 NEW) 12 | 13 | # Define build configuration option. 14 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 15 | if(IS_MULTICONFIG) 16 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" 17 | CACHE STRING "" FORCE) 18 | else() 19 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 20 | set(CMAKE_BUILD_TYPE "Debug" CACHE 21 | STRING "Flutter build mode" FORCE) 22 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 23 | "Debug" "Profile" "Release") 24 | endif() 25 | endif() 26 | # Define settings for the Profile build mode. 27 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") 28 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") 29 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") 30 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") 31 | 32 | # Use Unicode for all projects. 33 | add_definitions(-DUNICODE -D_UNICODE) 34 | 35 | # Compilation settings that should be applied to most targets. 36 | # 37 | # Be cautious about adding new options here, as plugins use this function by 38 | # default. In most cases, you should add new options to specific targets instead 39 | # of modifying this function. 40 | function(APPLY_STANDARD_SETTINGS TARGET) 41 | target_compile_features(${TARGET} PUBLIC cxx_std_17) 42 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") 43 | target_compile_options(${TARGET} PRIVATE /EHsc) 44 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") 45 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") 46 | endfunction() 47 | 48 | # Flutter library and tool build rules. 49 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 50 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 51 | 52 | # Application build; see runner/CMakeLists.txt. 53 | add_subdirectory("runner") 54 | 55 | # Generated plugin build rules, which manage building the plugins and adding 56 | # them to the application. 57 | include(flutter/generated_plugins.cmake) 58 | 59 | 60 | # === Installation === 61 | # Support files are copied into place next to the executable, so that it can 62 | # run in place. This is done instead of making a separate bundle (as on Linux) 63 | # so that building and running from within Visual Studio will work. 64 | set(BUILD_BUNDLE_DIR "$") 65 | # Make the "install" step default, as it's required to run. 66 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) 67 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 68 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 69 | endif() 70 | 71 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 72 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") 73 | 74 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 75 | COMPONENT Runtime) 76 | 77 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 78 | COMPONENT Runtime) 79 | 80 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 81 | COMPONENT Runtime) 82 | 83 | if(PLUGIN_BUNDLED_LIBRARIES) 84 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 85 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 86 | COMPONENT Runtime) 87 | endif() 88 | 89 | # Fully re-copy the assets directory on each build to avoid having stale files 90 | # from a previous install. 91 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 92 | install(CODE " 93 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 94 | " COMPONENT Runtime) 95 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 96 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 97 | 98 | # Install the AOT library on non-Debug builds only. 99 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 100 | CONFIGURATIONS Profile;Release 101 | COMPONENT Runtime) 102 | -------------------------------------------------------------------------------- /example/linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project-level configuration. 2 | cmake_minimum_required(VERSION 3.10) 3 | project(runner LANGUAGES CXX) 4 | 5 | # The name of the executable created for the application. Change this to change 6 | # the on-disk name of your application. 7 | set(BINARY_NAME "example") 8 | # The unique GTK application identifier for this application. See: 9 | # https://wiki.gnome.org/HowDoI/ChooseApplicationID 10 | set(APPLICATION_ID "com.example.example") 11 | 12 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent 13 | # versions of CMake. 14 | cmake_policy(SET CMP0063 NEW) 15 | 16 | # Load bundled libraries from the lib/ directory relative to the binary. 17 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 18 | 19 | # Root filesystem for cross-building. 20 | if(FLUTTER_TARGET_PLATFORM_SYSROOT) 21 | set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) 22 | set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) 23 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 24 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 25 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 26 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 27 | endif() 28 | 29 | # Define build configuration options. 30 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 31 | set(CMAKE_BUILD_TYPE "Debug" CACHE 32 | STRING "Flutter build mode" FORCE) 33 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 34 | "Debug" "Profile" "Release") 35 | endif() 36 | 37 | # Compilation settings that should be applied to most targets. 38 | # 39 | # Be cautious about adding new options here, as plugins use this function by 40 | # default. In most cases, you should add new options to specific targets instead 41 | # of modifying this function. 42 | function(APPLY_STANDARD_SETTINGS TARGET) 43 | target_compile_features(${TARGET} PUBLIC cxx_std_14) 44 | target_compile_options(${TARGET} PRIVATE -Wall -Werror) 45 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") 46 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") 47 | endfunction() 48 | 49 | # Flutter library and tool build rules. 50 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 51 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 52 | 53 | # System-level dependencies. 54 | find_package(PkgConfig REQUIRED) 55 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 56 | 57 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") 58 | 59 | # Define the application target. To change its name, change BINARY_NAME above, 60 | # not the value here, or `flutter run` will no longer work. 61 | # 62 | # Any new source files that you add to the application should be added here. 63 | add_executable(${BINARY_NAME} 64 | "main.cc" 65 | "my_application.cc" 66 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 67 | ) 68 | 69 | # Apply the standard set of build settings. This can be removed for applications 70 | # that need different build settings. 71 | apply_standard_settings(${BINARY_NAME}) 72 | 73 | # Add dependency libraries. Add any application-specific dependencies here. 74 | target_link_libraries(${BINARY_NAME} PRIVATE flutter) 75 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) 76 | 77 | # Run the Flutter tool portions of the build. This must not be removed. 78 | add_dependencies(${BINARY_NAME} flutter_assemble) 79 | 80 | # Only the install-generated bundle's copy of the executable will launch 81 | # correctly, since the resources must in the right relative locations. To avoid 82 | # people trying to run the unbundled copy, put it in a subdirectory instead of 83 | # the default top-level location. 84 | set_target_properties(${BINARY_NAME} 85 | PROPERTIES 86 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" 87 | ) 88 | 89 | # Generated plugin build rules, which manage building the plugins and adding 90 | # them to the application. 91 | include(flutter/generated_plugins.cmake) 92 | 93 | 94 | # === Installation === 95 | # By default, "installing" just makes a relocatable bundle in the build 96 | # directory. 97 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") 98 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 99 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 100 | endif() 101 | 102 | # Start with a clean build bundle directory every time. 103 | install(CODE " 104 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") 105 | " COMPONENT Runtime) 106 | 107 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 108 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") 109 | 110 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 111 | COMPONENT Runtime) 112 | 113 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 114 | COMPONENT Runtime) 115 | 116 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 117 | COMPONENT Runtime) 118 | 119 | foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) 120 | install(FILES "${bundled_library}" 121 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 122 | COMPONENT Runtime) 123 | endforeach(bundled_library) 124 | 125 | # Fully re-copy the assets directory on each build to avoid having stale files 126 | # from a previous install. 127 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 128 | install(CODE " 129 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 130 | " COMPONENT Runtime) 131 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 132 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 133 | 134 | # Install the AOT library on non-Debug builds only. 135 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") 136 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 137 | COMPONENT Runtime) 138 | endif() 139 | -------------------------------------------------------------------------------- /lib/src/theme.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/material.dart'; 24 | 25 | import './easy_loading.dart'; 26 | import './animations/animation.dart'; 27 | import './animations/opacity_animation.dart'; 28 | import './animations/offset_animation.dart'; 29 | import './animations/scale_animation.dart'; 30 | 31 | class EasyLoadingTheme { 32 | /// color of indicator 33 | static Color get indicatorColor => 34 | EasyLoading.instance.loadingStyle == EasyLoadingStyle.custom 35 | ? EasyLoading.instance.indicatorColor! 36 | : EasyLoading.instance.loadingStyle == EasyLoadingStyle.dark 37 | ? Colors.white 38 | : Colors.black; 39 | 40 | /// progress color of loading 41 | static Color get progressColor => 42 | EasyLoading.instance.loadingStyle == EasyLoadingStyle.custom 43 | ? EasyLoading.instance.progressColor! 44 | : EasyLoading.instance.loadingStyle == EasyLoadingStyle.dark 45 | ? Colors.white 46 | : Colors.black; 47 | 48 | /// background color of loading 49 | static Color get backgroundColor => 50 | EasyLoading.instance.loadingStyle == EasyLoadingStyle.custom 51 | ? EasyLoading.instance.backgroundColor! 52 | : EasyLoading.instance.loadingStyle == EasyLoadingStyle.dark 53 | ? Colors.black.withOpacity(0.9) 54 | : Colors.white; 55 | 56 | /// boxShadow color of loading 57 | static List? get boxShadow => 58 | EasyLoading.instance.loadingStyle == EasyLoadingStyle.custom 59 | ? EasyLoading.instance.boxShadow ?? [BoxShadow()] 60 | : null; 61 | 62 | /// font color of status 63 | static Color get textColor => 64 | EasyLoading.instance.loadingStyle == EasyLoadingStyle.custom 65 | ? EasyLoading.instance.textColor! 66 | : EasyLoading.instance.loadingStyle == EasyLoadingStyle.dark 67 | ? Colors.white 68 | : Colors.black; 69 | 70 | /// mask color of loading 71 | static Color maskColor(EasyLoadingMaskType? maskType) { 72 | maskType ??= EasyLoading.instance.maskType; 73 | return maskType == EasyLoadingMaskType.custom 74 | ? EasyLoading.instance.maskColor! 75 | : maskType == EasyLoadingMaskType.black 76 | ? Colors.black.withOpacity(0.5) 77 | : Colors.transparent; 78 | } 79 | 80 | /// loading animation 81 | static EasyLoadingAnimation get loadingAnimation { 82 | EasyLoadingAnimation _animation; 83 | switch (EasyLoading.instance.animationStyle) { 84 | case EasyLoadingAnimationStyle.custom: 85 | _animation = EasyLoading.instance.customAnimation!; 86 | break; 87 | case EasyLoadingAnimationStyle.offset: 88 | _animation = OffsetAnimation(); 89 | break; 90 | case EasyLoadingAnimationStyle.scale: 91 | _animation = ScaleAnimation(); 92 | break; 93 | default: 94 | _animation = OpacityAnimation(); 95 | break; 96 | } 97 | return _animation; 98 | } 99 | 100 | /// font size of status 101 | static double get fontSize => EasyLoading.instance.fontSize; 102 | 103 | /// size of indicator 104 | static double get indicatorSize => EasyLoading.instance.indicatorSize; 105 | 106 | /// width of progress indicator 107 | static double get progressWidth => EasyLoading.instance.progressWidth; 108 | 109 | /// width of indicator 110 | static double get lineWidth => EasyLoading.instance.lineWidth; 111 | 112 | /// loading indicator type 113 | static EasyLoadingIndicatorType get indicatorType => 114 | EasyLoading.instance.indicatorType; 115 | 116 | /// toast position 117 | static EasyLoadingToastPosition get toastPosition => 118 | EasyLoading.instance.toastPosition; 119 | 120 | /// toast position 121 | static AlignmentGeometry alignment(EasyLoadingToastPosition? position) => 122 | position == EasyLoadingToastPosition.bottom 123 | ? AlignmentDirectional.bottomCenter 124 | : (position == EasyLoadingToastPosition.top 125 | ? AlignmentDirectional.topCenter 126 | : AlignmentDirectional.center); 127 | 128 | /// display duration 129 | static Duration get displayDuration => EasyLoading.instance.displayDuration; 130 | 131 | /// animation duration 132 | static Duration get animationDuration => 133 | EasyLoading.instance.animationDuration; 134 | 135 | /// contentPadding of loading 136 | static EdgeInsets get contentPadding => EasyLoading.instance.contentPadding; 137 | 138 | /// padding of status 139 | static EdgeInsets get textPadding => EasyLoading.instance.textPadding; 140 | 141 | /// textAlign of status 142 | static TextAlign get textAlign => EasyLoading.instance.textAlign; 143 | 144 | /// textStyle of status 145 | static TextStyle? get textStyle => EasyLoading.instance.textStyle; 146 | 147 | /// radius of loading 148 | static double get radius => EasyLoading.instance.radius; 149 | 150 | /// should dismiss on user tap 151 | static bool? get dismissOnTap => EasyLoading.instance.dismissOnTap; 152 | 153 | static bool ignoring(EasyLoadingMaskType? maskType) { 154 | maskType ??= EasyLoading.instance.maskType; 155 | return EasyLoading.instance.userInteractions ?? 156 | (maskType == EasyLoadingMaskType.none ? true : false); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /README-zh_CN.md: -------------------------------------------------------------------------------- 1 | # Flutter EasyLoading 2 | 3 | [![pub package](https://img.shields.io/pub/v/flutter_easyloading?style=flat)](https://pub.dev/packages/flutter_easyloading) [![pub points](https://badges.bar/flutter_easyloading/pub%20points)](https://pub.dev/packages/flutter_easyloading/score) [![popularity](https://badges.bar/flutter_easyloading/popularity)](https://pub.dev/packages/flutter_easyloading/score) [![likes](https://badges.bar/flutter_easyloading/likes)](https://pub.dev/packages/flutter_easyloading/score) [![license](https://img.shields.io/github/license/nslogx/flutter_easyloading?style=flat)](https://github.com/nslogx/flutter_easyloading) [![stars](https://img.shields.io/github/stars/nslogx/flutter_easyloading?style=social)](https://github.com/nslogx/flutter_easyloading) 4 | 5 | [English](./README.md) | 简体中文 6 | 7 | 8 | 9 | ## 在线预览 10 | 11 | 👉 [https://nslogx.github.io/flutter_easyloading](https://nslogx.github.io/flutter_easyloading/#/) 12 | 13 | ## 安装 14 | 15 | 将以下代码添加到您项目中的 `pubspec.yaml` 文件: 16 | 17 | ```yaml 18 | dependencies: 19 | flutter_easyloading: ^latest 20 | ``` 21 | 22 | ## 导入 23 | 24 | ```dart 25 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 26 | ``` 27 | 28 | ## 如何使用 29 | 30 | 首先, 在`MaterialApp`/`CupertinoApp`中初始化`FlutterEasyLoading`: 31 | 32 | ```dart 33 | class MyApp extends StatelessWidget { 34 | @override 35 | Widget build(BuildContext context) { 36 | return MaterialApp( 37 | title: 'Flutter EasyLoading', 38 | theme: ThemeData( 39 | primarySwatch: Colors.blue, 40 | ), 41 | home: MyHomePage(title: 'Flutter EasyLoading'), 42 | builder: EasyLoading.init(), 43 | ); 44 | } 45 | } 46 | ``` 47 | 48 | 然后, 请尽情使用吧: 49 | 50 | ```dart 51 | EasyLoading.show(status: 'loading...'); 52 | 53 | EasyLoading.showProgress(0.3, status: 'downloading...'); 54 | 55 | EasyLoading.showSuccess('Great Success!'); 56 | 57 | EasyLoading.showError('Failed with Error'); 58 | 59 | EasyLoading.showInfo('Useful Information.'); 60 | 61 | EasyLoading.showToast('Toast'); 62 | 63 | EasyLoading.dismiss(); 64 | ``` 65 | 66 | 添加 Loading 状态回调 67 | 68 | ```dart 69 | EasyLoading.addStatusCallback((status) { 70 | print('EasyLoading Status $status'); 71 | }); 72 | ``` 73 | 74 | 移除 Loading 状态回调 75 | 76 | ```dart 77 | EasyLoading.removeCallback(statusCallback); 78 | 79 | EasyLoading.removeAllCallbacks(); 80 | ``` 81 | 82 | ## 自定义 83 | 84 | ❗️**注意:** 85 | 86 | - **`textColor`、`indicatorColor`、`progressColor`、`backgroundColor` 仅对 `EasyLoadingStyle.custom`有效。** 87 | 88 | - **`maskColor` 仅对 `EasyLoadingMaskType.custom`有效。** 89 | 90 | ```dart 91 | /// loading的样式, 默认[EasyLoadingStyle.dark]. 92 | EasyLoadingStyle loadingStyle; 93 | 94 | /// loading的指示器类型, 默认[EasyLoadingIndicatorType.fadingCircle]. 95 | EasyLoadingIndicatorType indicatorType; 96 | 97 | /// loading的遮罩类型, 默认[EasyLoadingMaskType.none]. 98 | EasyLoadingMaskType maskType; 99 | 100 | /// toast的位置, 默认 [EasyLoadingToastPosition.center]. 101 | EasyLoadingToastPosition toastPosition; 102 | 103 | /// 动画类型, 默认 [EasyLoadingAnimationStyle.opacity]. 104 | EasyLoadingAnimationStyle animationStyle; 105 | 106 | /// 自定义动画, 默认 null. 107 | EasyLoadingAnimation customAnimation; 108 | 109 | /// 文本的对齐方式 , 默认[TextAlign.center]. 110 | TextAlign textAlign; 111 | 112 | /// 文本的样式 , 默认 null. 113 | TextStyle textStyle; 114 | 115 | /// loading内容区域的内边距. 116 | EdgeInsets contentPadding; 117 | 118 | /// 文本的内边距. 119 | EdgeInsets textPadding; 120 | 121 | /// 指示器的大小, 默认40.0. 122 | double indicatorSize; 123 | 124 | /// loading的圆角大小, 默认5.0. 125 | double radius; 126 | 127 | /// 文本大小, 默认15.0. 128 | double fontSize; 129 | 130 | /// 进度条指示器的宽度, 默认2.0. 131 | double progressWidth; 132 | 133 | /// 指示器的宽度, 默认4.0, 仅对[EasyLoadingIndicatorType.ring, EasyLoadingIndicatorType.dualRing]有效. 134 | double lineWidth; 135 | 136 | /// [showSuccess] [showError] [showInfo]的展示时间, 默认2000ms. 137 | Duration displayDuration; 138 | 139 | /// 动画时间, 默认200ms. 140 | Duration animationDuration; 141 | 142 | /// 文本的颜色, 仅对[EasyLoadingStyle.custom]有效. 143 | Color textColor; 144 | 145 | /// 指示器的颜色, 仅对[EasyLoadingStyle.custom]有效. 146 | Color indicatorColor; 147 | 148 | /// 进度条指示器的颜色, 仅对[EasyLoadingStyle.custom]有效. 149 | Color progressColor; 150 | 151 | /// loading的背景色, 仅对[EasyLoadingStyle.custom]有效. 152 | Color backgroundColor; 153 | 154 | /// 遮罩的背景色, 仅对[EasyLoadingMaskType.custom]有效. 155 | Color maskColor; 156 | 157 | /// 当loading展示的时候,是否允许用户操作. 158 | bool userInteractions; 159 | 160 | /// 点击背景是否关闭. 161 | bool dismissOnTap; 162 | 163 | /// 指示器自定义组件 164 | Widget indicatorWidget; 165 | 166 | /// 展示成功状态的自定义组件 167 | Widget successWidget; 168 | 169 | /// 展示失败状态的自定义组件 170 | Widget errorWidget; 171 | 172 | /// 展示信息状态的自定义组件 173 | Widget infoWidget; 174 | ``` 175 | 176 | 因为 `EasyLoading` 是一个全局单例, 所以你可以在任意一个地方自定义它的样式: 177 | 178 | ```dart 179 | EasyLoading.instance 180 | ..displayDuration = const Duration(milliseconds: 2000) 181 | ..indicatorType = EasyLoadingIndicatorType.fadingCircle 182 | ..loadingStyle = EasyLoadingStyle.dark 183 | ..indicatorSize = 45.0 184 | ..radius = 10.0 185 | ..progressColor = Colors.yellow 186 | ..backgroundColor = Colors.green 187 | ..indicatorColor = Colors.yellow 188 | ..textColor = Colors.yellow 189 | ..maskColor = Colors.blue.withOpacity(0.5) 190 | ..userInteractions = true 191 | ..dismissOnTap = false 192 | ..customAnimation = CustomAnimation(); 193 | ``` 194 | 195 | 更多的指示器类型可查看 👉 [flutter_spinkit showcase](https://github.com/jogboms/flutter_spinkit#-showcase) 196 | 197 | ## 自定义动画 198 | 199 | 例子: 👉 [Custom Animation](https://github.com/nslogx/flutter_easyloading/blob/develop/example/lib/custom_animation.dart) 200 | 201 | ## 待完成 202 | 203 | - [x] 新增进度条指示器 204 | 205 | - [x] 新增自定义动画 206 | 207 | ## 更新日志 208 | 209 | [CHANGELOG](./CHANGELOG.md) 210 | 211 | ## 开源许可协议 212 | 213 | [MIT License](./LICENSE) 214 | 215 | ## ❤️❤️❤️ 216 | 217 | 感谢 [flutter_spinkit](https://github.com/jogboms/flutter_spinkit) ❤️ 218 | 219 | 感谢 [JetBrains Open Source](https://www.jetbrains.com/community/opensource/#support) 提供支持 220 | 221 | [](https://www.jetbrains.com/?from=FlutterEasyLoading) 222 | -------------------------------------------------------------------------------- /lib/src/widgets/indicator.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'package:flutter/material.dart'; 24 | import 'package:flutter_spinkit/flutter_spinkit.dart'; 25 | 26 | import '../easy_loading.dart'; 27 | import '../theme.dart'; 28 | 29 | class LoadingIndicator extends StatefulWidget { 30 | const LoadingIndicator({ 31 | Key? key, 32 | }) : super(key: key); 33 | 34 | @override 35 | _LoadingIndicatorState createState() => _LoadingIndicatorState(); 36 | } 37 | 38 | class _LoadingIndicatorState extends State { 39 | final double _size = EasyLoadingTheme.indicatorSize; 40 | 41 | /// indicator color of loading 42 | final Color _indicatorColor = EasyLoadingTheme.indicatorColor; 43 | late Widget _indicator; 44 | 45 | @override 46 | void initState() { 47 | super.initState(); 48 | } 49 | 50 | @override 51 | void dispose() { 52 | super.dispose(); 53 | } 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | double _width = _size; 58 | switch (EasyLoadingTheme.indicatorType) { 59 | case EasyLoadingIndicatorType.fadingCircle: 60 | _indicator = SpinKitFadingCircle( 61 | color: _indicatorColor, 62 | size: _size, 63 | ); 64 | break; 65 | case EasyLoadingIndicatorType.circle: 66 | _indicator = SpinKitCircle( 67 | color: _indicatorColor, 68 | size: _size, 69 | ); 70 | break; 71 | case EasyLoadingIndicatorType.threeBounce: 72 | _indicator = SpinKitThreeBounce( 73 | color: _indicatorColor, 74 | size: _size, 75 | ); 76 | _width = _size * 2; 77 | break; 78 | case EasyLoadingIndicatorType.chasingDots: 79 | _indicator = SpinKitChasingDots( 80 | color: _indicatorColor, 81 | size: _size, 82 | ); 83 | break; 84 | case EasyLoadingIndicatorType.wave: 85 | _indicator = SpinKitWave( 86 | color: _indicatorColor, 87 | size: _size, 88 | itemCount: 6, 89 | ); 90 | _width = _size * 1.25; 91 | break; 92 | case EasyLoadingIndicatorType.wanderingCubes: 93 | _indicator = SpinKitWanderingCubes( 94 | color: _indicatorColor, 95 | size: _size, 96 | ); 97 | break; 98 | case EasyLoadingIndicatorType.rotatingCircle: 99 | _indicator = SpinKitRotatingCircle( 100 | color: _indicatorColor, 101 | size: _size, 102 | ); 103 | break; 104 | case EasyLoadingIndicatorType.rotatingPlain: 105 | _indicator = SpinKitRotatingPlain( 106 | color: _indicatorColor, 107 | size: _size, 108 | ); 109 | break; 110 | case EasyLoadingIndicatorType.doubleBounce: 111 | _indicator = SpinKitDoubleBounce( 112 | color: _indicatorColor, 113 | size: _size, 114 | ); 115 | break; 116 | case EasyLoadingIndicatorType.fadingFour: 117 | _indicator = SpinKitFadingFour( 118 | color: _indicatorColor, 119 | size: _size, 120 | ); 121 | break; 122 | case EasyLoadingIndicatorType.fadingCube: 123 | _indicator = SpinKitFadingCube( 124 | color: _indicatorColor, 125 | size: _size, 126 | ); 127 | break; 128 | case EasyLoadingIndicatorType.pulse: 129 | _indicator = SpinKitPulse( 130 | color: _indicatorColor, 131 | size: _size, 132 | ); 133 | break; 134 | case EasyLoadingIndicatorType.cubeGrid: 135 | _indicator = SpinKitCubeGrid( 136 | color: _indicatorColor, 137 | size: _size, 138 | ); 139 | break; 140 | case EasyLoadingIndicatorType.foldingCube: 141 | _indicator = SpinKitFoldingCube( 142 | color: _indicatorColor, 143 | size: _size, 144 | ); 145 | break; 146 | case EasyLoadingIndicatorType.pumpingHeart: 147 | _indicator = SpinKitPumpingHeart( 148 | color: _indicatorColor, 149 | size: _size, 150 | ); 151 | break; 152 | case EasyLoadingIndicatorType.dualRing: 153 | _indicator = SpinKitDualRing( 154 | color: _indicatorColor, 155 | size: _size, 156 | lineWidth: EasyLoadingTheme.lineWidth, 157 | ); 158 | break; 159 | case EasyLoadingIndicatorType.hourGlass: 160 | _indicator = SpinKitHourGlass( 161 | color: _indicatorColor, 162 | size: _size, 163 | ); 164 | break; 165 | case EasyLoadingIndicatorType.pouringHourGlass: 166 | _indicator = SpinKitPouringHourGlass( 167 | color: _indicatorColor, 168 | size: _size, 169 | ); 170 | break; 171 | case EasyLoadingIndicatorType.fadingGrid: 172 | _indicator = SpinKitFadingGrid( 173 | color: _indicatorColor, 174 | size: _size, 175 | ); 176 | break; 177 | case EasyLoadingIndicatorType.ring: 178 | _indicator = SpinKitRing( 179 | color: _indicatorColor, 180 | size: _size, 181 | lineWidth: EasyLoadingTheme.lineWidth, 182 | ); 183 | break; 184 | case EasyLoadingIndicatorType.ripple: 185 | _indicator = SpinKitRipple( 186 | color: _indicatorColor, 187 | size: _size, 188 | ); 189 | break; 190 | case EasyLoadingIndicatorType.spinningCircle: 191 | _indicator = SpinKitSpinningCircle( 192 | color: _indicatorColor, 193 | size: _size, 194 | ); 195 | break; 196 | case EasyLoadingIndicatorType.squareCircle: 197 | _indicator = SpinKitSquareCircle( 198 | color: _indicatorColor, 199 | size: _size, 200 | ); 201 | break; 202 | default: 203 | _indicator = SpinKitFadingCircle( 204 | color: _indicatorColor, 205 | size: _size, 206 | ); 207 | break; 208 | } 209 | 210 | return Container( 211 | constraints: BoxConstraints( 212 | maxWidth: _width, 213 | ), 214 | child: _indicator, 215 | ); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter EasyLoading 2 | 3 | [![pub package](https://img.shields.io/pub/v/flutter_easyloading?style=flat)](https://pub.dev/packages/flutter_easyloading) [![pub points](https://badges.bar/flutter_easyloading/pub%20points)](https://pub.dev/packages/flutter_easyloading/score) [![popularity](https://badges.bar/flutter_easyloading/popularity)](https://pub.dev/packages/flutter_easyloading/score) [![likes](https://badges.bar/flutter_easyloading/likes)](https://pub.dev/packages/flutter_easyloading/score) [![license](https://img.shields.io/github/license/nslogx/flutter_easyloading?style=flat)](https://github.com/nslogx/flutter_easyloading) [![stars](https://img.shields.io/github/stars/nslogx/flutter_easyloading?style=social)](https://github.com/nslogx/flutter_easyloading) 4 | 5 | English | [简体中文](./README-zh_CN.md) 6 | 7 | 8 | 9 | ## Live Preview 10 | 11 | 👉 [https://nslogx.github.io/flutter_easyloading](https://nslogx.github.io/flutter_easyloading/#/) 12 | 13 | ## Installing 14 | 15 | Add this to your package's `pubspec.yaml` file: 16 | 17 | ```yaml 18 | dependencies: 19 | flutter_easyloading: ^latest 20 | ``` 21 | 22 | ## Import 23 | 24 | ```dart 25 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 26 | ``` 27 | 28 | ## How to use 29 | 30 | First, initialize `EasyLoading` in your `MaterialApp`/`CupertinoApp`: 31 | 32 | ```dart 33 | class MyApp extends StatelessWidget { 34 | // This widget is the root of your application. 35 | @override 36 | Widget build(BuildContext context) { 37 | return MaterialApp( 38 | title: 'Flutter EasyLoading', 39 | theme: ThemeData( 40 | primarySwatch: Colors.blue, 41 | ), 42 | home: MyHomePage(title: 'Flutter EasyLoading'), 43 | builder: EasyLoading.init(), 44 | ); 45 | } 46 | } 47 | ``` 48 | 49 | Then, enjoy yourself: 50 | 51 | ```dart 52 | EasyLoading.show(status: 'loading...'); 53 | 54 | EasyLoading.showProgress(0.3, status: 'downloading...'); 55 | 56 | EasyLoading.showSuccess('Great Success!'); 57 | 58 | EasyLoading.showError('Failed with Error'); 59 | 60 | EasyLoading.showInfo('Useful Information.'); 61 | 62 | EasyLoading.showToast('Toast'); 63 | 64 | EasyLoading.dismiss(); 65 | ``` 66 | 67 | Add loading status callback 68 | 69 | ```dart 70 | EasyLoading.addStatusCallback((status) { 71 | print('EasyLoading Status $status'); 72 | }); 73 | ``` 74 | 75 | Remove loading status callback(s) 76 | 77 | ```dart 78 | EasyLoading.removeCallback(statusCallback); 79 | 80 | EasyLoading.removeAllCallbacks(); 81 | ``` 82 | 83 | ## Customize 84 | 85 | ❗️**Note:** 86 | 87 | - **`textColor`、`indicatorColor`、`progressColor`、`backgroundColor` only used for `EasyLoadingStyle.custom`.** 88 | 89 | - **`maskColor` only used for `EasyLoadingMaskType.custom`.** 90 | 91 | ```dart 92 | /// loading style, default [EasyLoadingStyle.dark]. 93 | EasyLoadingStyle loadingStyle; 94 | 95 | /// loading indicator type, default [EasyLoadingIndicatorType.fadingCircle]. 96 | EasyLoadingIndicatorType indicatorType; 97 | 98 | /// loading mask type, default [EasyLoadingMaskType.none]. 99 | EasyLoadingMaskType maskType; 100 | 101 | /// toast position, default [EasyLoadingToastPosition.center]. 102 | EasyLoadingToastPosition toastPosition; 103 | 104 | /// loading animationStyle, default [EasyLoadingAnimationStyle.opacity]. 105 | EasyLoadingAnimationStyle animationStyle; 106 | 107 | /// loading custom animation, default null. 108 | EasyLoadingAnimation customAnimation; 109 | 110 | /// textAlign of status, default [TextAlign.center]. 111 | TextAlign textAlign; 112 | 113 | /// textStyle of status, default null. 114 | TextStyle textStyle; 115 | 116 | /// content padding of loading. 117 | EdgeInsets contentPadding; 118 | 119 | /// padding of [status]. 120 | EdgeInsets textPadding; 121 | 122 | /// size of indicator, default 40.0. 123 | double indicatorSize; 124 | 125 | /// radius of loading, default 5.0. 126 | double radius; 127 | 128 | /// fontSize of loading, default 15.0. 129 | double fontSize; 130 | 131 | /// width of progress indicator, default 2.0. 132 | double progressWidth; 133 | 134 | /// width of indicator, default 4.0, only used for [EasyLoadingIndicatorType.ring, EasyLoadingIndicatorType.dualRing]. 135 | double lineWidth; 136 | 137 | /// display duration of [showSuccess] [showError] [showInfo], default 2000ms. 138 | Duration displayDuration; 139 | 140 | /// animation duration of indicator, default 200ms. 141 | Duration animationDuration; 142 | 143 | /// color of loading status, only used for [EasyLoadingStyle.custom]. 144 | Color textColor; 145 | 146 | /// color of loading indicator, only used for [EasyLoadingStyle.custom]. 147 | Color indicatorColor; 148 | 149 | /// progress color of loading, only used for [EasyLoadingStyle.custom]. 150 | Color progressColor; 151 | 152 | /// background color of loading, only used for [EasyLoadingStyle.custom]. 153 | Color backgroundColor; 154 | 155 | /// mask color of loading, only used for [EasyLoadingMaskType.custom]. 156 | Color maskColor; 157 | 158 | /// should allow user interactions while loading is displayed. 159 | bool userInteractions; 160 | 161 | /// should dismiss on user tap. 162 | bool dismissOnTap; 163 | 164 | /// indicator widget of loading 165 | Widget indicatorWidget; 166 | 167 | /// success widget of loading 168 | Widget successWidget; 169 | 170 | /// error widget of loading 171 | Widget errorWidget; 172 | 173 | /// info widget of loading 174 | Widget infoWidget; 175 | ``` 176 | 177 | Because of `EasyLoading` is a singleton, so you can custom loading style any where like this: 178 | 179 | ```dart 180 | EasyLoading.instance 181 | ..displayDuration = const Duration(milliseconds: 2000) 182 | ..indicatorType = EasyLoadingIndicatorType.fadingCircle 183 | ..loadingStyle = EasyLoadingStyle.dark 184 | ..indicatorSize = 45.0 185 | ..radius = 10.0 186 | ..progressColor = Colors.yellow 187 | ..backgroundColor = Colors.green 188 | ..indicatorColor = Colors.yellow 189 | ..textColor = Colors.yellow 190 | ..maskColor = Colors.blue.withOpacity(0.5) 191 | ..userInteractions = true 192 | ..dismissOnTap = false 193 | ..customAnimation = CustomAnimation(); 194 | ``` 195 | 196 | More indicatorType can see in 👉 [flutter_spinkit showcase](https://github.com/jogboms/flutter_spinkit#-showcase) 197 | 198 | ## Custom Animation 199 | 200 | example: 👉 [Custom Animation](https://github.com/nslogx/flutter_easyloading/blob/develop/example/lib/custom_animation.dart) 201 | 202 | ## Todo 203 | 204 | - [x] add progress indicator 205 | 206 | - [x] add custom animation 207 | 208 | ## Changelog 209 | 210 | [CHANGELOG](./CHANGELOG.md) 211 | 212 | ## License 213 | 214 | [MIT License](./LICENSE) 215 | 216 | ## ❤️❤️❤️ 217 | 218 | Thanks to [flutter_spinkit](https://github.com/jogboms/flutter_spinkit) ❤️ 219 | 220 | Supported by [JetBrains Open Source](https://www.jetbrains.com/community/opensource/#support) 221 | 222 | [](https://www.jetbrains.com/?from=FlutterEasyLoading) 223 | 224 | -------------------------------------------------------------------------------- /example/windows/runner/win32_window.cpp: -------------------------------------------------------------------------------- 1 | #include "win32_window.h" 2 | 3 | #include 4 | 5 | #include "resource.h" 6 | 7 | namespace { 8 | 9 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; 10 | 11 | // The number of Win32Window objects that currently exist. 12 | static int g_active_window_count = 0; 13 | 14 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); 15 | 16 | // Scale helper to convert logical scaler values to physical using passed in 17 | // scale factor 18 | int Scale(int source, double scale_factor) { 19 | return static_cast(source * scale_factor); 20 | } 21 | 22 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. 23 | // This API is only needed for PerMonitor V1 awareness mode. 24 | void EnableFullDpiSupportIfAvailable(HWND hwnd) { 25 | HMODULE user32_module = LoadLibraryA("User32.dll"); 26 | if (!user32_module) { 27 | return; 28 | } 29 | auto enable_non_client_dpi_scaling = 30 | reinterpret_cast( 31 | GetProcAddress(user32_module, "EnableNonClientDpiScaling")); 32 | if (enable_non_client_dpi_scaling != nullptr) { 33 | enable_non_client_dpi_scaling(hwnd); 34 | FreeLibrary(user32_module); 35 | } 36 | } 37 | 38 | } // namespace 39 | 40 | // Manages the Win32Window's window class registration. 41 | class WindowClassRegistrar { 42 | public: 43 | ~WindowClassRegistrar() = default; 44 | 45 | // Returns the singleton registar instance. 46 | static WindowClassRegistrar* GetInstance() { 47 | if (!instance_) { 48 | instance_ = new WindowClassRegistrar(); 49 | } 50 | return instance_; 51 | } 52 | 53 | // Returns the name of the window class, registering the class if it hasn't 54 | // previously been registered. 55 | const wchar_t* GetWindowClass(); 56 | 57 | // Unregisters the window class. Should only be called if there are no 58 | // instances of the window. 59 | void UnregisterWindowClass(); 60 | 61 | private: 62 | WindowClassRegistrar() = default; 63 | 64 | static WindowClassRegistrar* instance_; 65 | 66 | bool class_registered_ = false; 67 | }; 68 | 69 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; 70 | 71 | const wchar_t* WindowClassRegistrar::GetWindowClass() { 72 | if (!class_registered_) { 73 | WNDCLASS window_class{}; 74 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); 75 | window_class.lpszClassName = kWindowClassName; 76 | window_class.style = CS_HREDRAW | CS_VREDRAW; 77 | window_class.cbClsExtra = 0; 78 | window_class.cbWndExtra = 0; 79 | window_class.hInstance = GetModuleHandle(nullptr); 80 | window_class.hIcon = 81 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); 82 | window_class.hbrBackground = 0; 83 | window_class.lpszMenuName = nullptr; 84 | window_class.lpfnWndProc = Win32Window::WndProc; 85 | RegisterClass(&window_class); 86 | class_registered_ = true; 87 | } 88 | return kWindowClassName; 89 | } 90 | 91 | void WindowClassRegistrar::UnregisterWindowClass() { 92 | UnregisterClass(kWindowClassName, nullptr); 93 | class_registered_ = false; 94 | } 95 | 96 | Win32Window::Win32Window() { 97 | ++g_active_window_count; 98 | } 99 | 100 | Win32Window::~Win32Window() { 101 | --g_active_window_count; 102 | Destroy(); 103 | } 104 | 105 | bool Win32Window::CreateAndShow(const std::wstring& title, 106 | const Point& origin, 107 | const Size& size) { 108 | Destroy(); 109 | 110 | const wchar_t* window_class = 111 | WindowClassRegistrar::GetInstance()->GetWindowClass(); 112 | 113 | const POINT target_point = {static_cast(origin.x), 114 | static_cast(origin.y)}; 115 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); 116 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); 117 | double scale_factor = dpi / 96.0; 118 | 119 | HWND window = CreateWindow( 120 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 121 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), 122 | Scale(size.width, scale_factor), Scale(size.height, scale_factor), 123 | nullptr, nullptr, GetModuleHandle(nullptr), this); 124 | 125 | if (!window) { 126 | return false; 127 | } 128 | 129 | return OnCreate(); 130 | } 131 | 132 | // static 133 | LRESULT CALLBACK Win32Window::WndProc(HWND const window, 134 | UINT const message, 135 | WPARAM const wparam, 136 | LPARAM const lparam) noexcept { 137 | if (message == WM_NCCREATE) { 138 | auto window_struct = reinterpret_cast(lparam); 139 | SetWindowLongPtr(window, GWLP_USERDATA, 140 | reinterpret_cast(window_struct->lpCreateParams)); 141 | 142 | auto that = static_cast(window_struct->lpCreateParams); 143 | EnableFullDpiSupportIfAvailable(window); 144 | that->window_handle_ = window; 145 | } else if (Win32Window* that = GetThisFromHandle(window)) { 146 | return that->MessageHandler(window, message, wparam, lparam); 147 | } 148 | 149 | return DefWindowProc(window, message, wparam, lparam); 150 | } 151 | 152 | LRESULT 153 | Win32Window::MessageHandler(HWND hwnd, 154 | UINT const message, 155 | WPARAM const wparam, 156 | LPARAM const lparam) noexcept { 157 | switch (message) { 158 | case WM_DESTROY: 159 | window_handle_ = nullptr; 160 | Destroy(); 161 | if (quit_on_close_) { 162 | PostQuitMessage(0); 163 | } 164 | return 0; 165 | 166 | case WM_DPICHANGED: { 167 | auto newRectSize = reinterpret_cast(lparam); 168 | LONG newWidth = newRectSize->right - newRectSize->left; 169 | LONG newHeight = newRectSize->bottom - newRectSize->top; 170 | 171 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, 172 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE); 173 | 174 | return 0; 175 | } 176 | case WM_SIZE: { 177 | RECT rect = GetClientArea(); 178 | if (child_content_ != nullptr) { 179 | // Size and position the child window. 180 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, 181 | rect.bottom - rect.top, TRUE); 182 | } 183 | return 0; 184 | } 185 | 186 | case WM_ACTIVATE: 187 | if (child_content_ != nullptr) { 188 | SetFocus(child_content_); 189 | } 190 | return 0; 191 | } 192 | 193 | return DefWindowProc(window_handle_, message, wparam, lparam); 194 | } 195 | 196 | void Win32Window::Destroy() { 197 | OnDestroy(); 198 | 199 | if (window_handle_) { 200 | DestroyWindow(window_handle_); 201 | window_handle_ = nullptr; 202 | } 203 | if (g_active_window_count == 0) { 204 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); 205 | } 206 | } 207 | 208 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { 209 | return reinterpret_cast( 210 | GetWindowLongPtr(window, GWLP_USERDATA)); 211 | } 212 | 213 | void Win32Window::SetChildContent(HWND content) { 214 | child_content_ = content; 215 | SetParent(content, window_handle_); 216 | RECT frame = GetClientArea(); 217 | 218 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left, 219 | frame.bottom - frame.top, true); 220 | 221 | SetFocus(child_content_); 222 | } 223 | 224 | RECT Win32Window::GetClientArea() { 225 | RECT frame; 226 | GetClientRect(window_handle_, &frame); 227 | return frame; 228 | } 229 | 230 | HWND Win32Window::GetHandle() { 231 | return window_handle_; 232 | } 233 | 234 | void Win32Window::SetQuitOnClose(bool quit_on_close) { 235 | quit_on_close_ = quit_on_close; 236 | } 237 | 238 | bool Win32Window::OnCreate() { 239 | // No-op; provided for subclasses. 240 | return true; 241 | } 242 | 243 | void Win32Window::OnDestroy() { 244 | // No-op; provided for subclasses. 245 | } 246 | -------------------------------------------------------------------------------- /lib/src/widgets/container.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'dart:async'; 24 | 25 | import 'package:flutter/material.dart'; 26 | import 'package:flutter/scheduler.dart'; 27 | 28 | import '../theme.dart'; 29 | import '../easy_loading.dart'; 30 | 31 | //https://docs.flutter.dev/development/tools/sdk/release-notes/release-notes-3.0.0 32 | T? _ambiguate(T? value) => value; 33 | 34 | class EasyLoadingContainer extends StatefulWidget { 35 | final Widget? indicator; 36 | final String? status; 37 | final bool? dismissOnTap; 38 | final EasyLoadingToastPosition? toastPosition; 39 | final EasyLoadingMaskType? maskType; 40 | final Completer? completer; 41 | final bool animation; 42 | 43 | const EasyLoadingContainer({ 44 | Key? key, 45 | this.indicator, 46 | this.status, 47 | this.dismissOnTap, 48 | this.toastPosition, 49 | this.maskType, 50 | this.completer, 51 | this.animation = true, 52 | }) : super(key: key); 53 | 54 | @override 55 | EasyLoadingContainerState createState() => EasyLoadingContainerState(); 56 | } 57 | 58 | class EasyLoadingContainerState extends State 59 | with SingleTickerProviderStateMixin { 60 | String? _status; 61 | Color? _maskColor; 62 | late AnimationController _animationController; 63 | late AlignmentGeometry _alignment; 64 | late bool _dismissOnTap, _ignoring; 65 | 66 | //https://docs.flutter.dev/development/tools/sdk/release-notes/release-notes-3.0.0 67 | bool get isPersistentCallbacks => 68 | _ambiguate(SchedulerBinding.instance)!.schedulerPhase == 69 | SchedulerPhase.persistentCallbacks; 70 | 71 | @override 72 | void initState() { 73 | super.initState(); 74 | if (!mounted) return; 75 | _status = widget.status; 76 | _alignment = (widget.indicator == null && widget.status?.isNotEmpty == true) 77 | ? EasyLoadingTheme.alignment(widget.toastPosition) 78 | : AlignmentDirectional.center; 79 | _dismissOnTap = 80 | widget.dismissOnTap ?? (EasyLoadingTheme.dismissOnTap ?? false); 81 | _ignoring = 82 | _dismissOnTap ? false : EasyLoadingTheme.ignoring(widget.maskType); 83 | _maskColor = EasyLoadingTheme.maskColor(widget.maskType); 84 | _animationController = AnimationController( 85 | vsync: this, 86 | duration: EasyLoadingTheme.animationDuration, 87 | )..addStatusListener((status) { 88 | bool isCompleted = widget.completer?.isCompleted ?? false; 89 | if (status == AnimationStatus.completed && !isCompleted) { 90 | widget.completer?.complete(); 91 | } 92 | }); 93 | show(widget.animation); 94 | } 95 | 96 | @override 97 | void dispose() { 98 | _animationController.dispose(); 99 | super.dispose(); 100 | } 101 | 102 | Future show(bool animation) { 103 | if (isPersistentCallbacks) { 104 | Completer completer = Completer(); 105 | _ambiguate(SchedulerBinding.instance)!.addPostFrameCallback((_) => 106 | completer 107 | .complete(_animationController.forward(from: animation ? 0 : 1))); 108 | return completer.future; 109 | } else { 110 | return _animationController.forward(from: animation ? 0 : 1); 111 | } 112 | } 113 | 114 | Future dismiss(bool animation) { 115 | if (isPersistentCallbacks) { 116 | Completer completer = Completer(); 117 | _ambiguate(SchedulerBinding.instance)!.addPostFrameCallback((_) => 118 | completer 119 | .complete(_animationController.reverse(from: animation ? 1 : 0))); 120 | return completer.future; 121 | } else { 122 | return _animationController.reverse(from: animation ? 1 : 0); 123 | } 124 | } 125 | 126 | void updateStatus(String status) { 127 | if (_status == status) return; 128 | setState(() { 129 | _status = status; 130 | }); 131 | } 132 | 133 | void _onTap() async { 134 | if (_dismissOnTap) await EasyLoading.dismiss(); 135 | } 136 | 137 | @override 138 | Widget build(BuildContext context) { 139 | return Stack( 140 | alignment: _alignment, 141 | children: [ 142 | AnimatedBuilder( 143 | animation: _animationController, 144 | builder: (BuildContext context, Widget? child) { 145 | return Opacity( 146 | opacity: _animationController.value, 147 | child: IgnorePointer( 148 | ignoring: _ignoring, 149 | child: _dismissOnTap 150 | ? GestureDetector( 151 | onTap: _onTap, 152 | behavior: HitTestBehavior.translucent, 153 | child: Container( 154 | width: double.infinity, 155 | height: double.infinity, 156 | color: _maskColor, 157 | ), 158 | ) 159 | : Container( 160 | width: double.infinity, 161 | height: double.infinity, 162 | color: _maskColor, 163 | ), 164 | ), 165 | ); 166 | }, 167 | ), 168 | AnimatedBuilder( 169 | animation: _animationController, 170 | builder: (BuildContext context, Widget? child) { 171 | return EasyLoadingTheme.loadingAnimation.buildWidget( 172 | _Indicator( 173 | status: _status, 174 | indicator: widget.indicator, 175 | ), 176 | _animationController, 177 | _alignment, 178 | ); 179 | }, 180 | ), 181 | ], 182 | ); 183 | } 184 | } 185 | 186 | class _Indicator extends StatelessWidget { 187 | final Widget? indicator; 188 | final String? status; 189 | 190 | const _Indicator({ 191 | required this.indicator, 192 | required this.status, 193 | }); 194 | 195 | @override 196 | Widget build(BuildContext context) { 197 | return Container( 198 | margin: const EdgeInsets.all(50.0), 199 | decoration: BoxDecoration( 200 | color: EasyLoadingTheme.backgroundColor, 201 | borderRadius: BorderRadius.circular( 202 | EasyLoadingTheme.radius, 203 | ), 204 | boxShadow: EasyLoadingTheme.boxShadow, 205 | ), 206 | padding: EasyLoadingTheme.contentPadding, 207 | child: Column( 208 | mainAxisAlignment: MainAxisAlignment.center, 209 | crossAxisAlignment: CrossAxisAlignment.center, 210 | mainAxisSize: MainAxisSize.min, 211 | children: [ 212 | if (indicator != null) 213 | Container( 214 | margin: status?.isNotEmpty == true 215 | ? EasyLoadingTheme.textPadding 216 | : EdgeInsets.zero, 217 | child: indicator, 218 | ), 219 | if (status != null) 220 | Text( 221 | status!, 222 | style: EasyLoadingTheme.textStyle ?? 223 | TextStyle( 224 | color: EasyLoadingTheme.textColor, 225 | fontSize: EasyLoadingTheme.fontSize, 226 | ), 227 | textAlign: EasyLoadingTheme.textAlign, 228 | ), 229 | ], 230 | ), 231 | ); 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/cupertino.dart'; 5 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 6 | 7 | import './custom_animation.dart'; 8 | 9 | import './test.dart'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | configLoading(); 14 | } 15 | 16 | void configLoading() { 17 | EasyLoading.instance 18 | ..displayDuration = const Duration(milliseconds: 2000) 19 | ..indicatorType = EasyLoadingIndicatorType.fadingCircle 20 | ..loadingStyle = EasyLoadingStyle.dark 21 | ..indicatorSize = 45.0 22 | ..radius = 10.0 23 | ..progressColor = Colors.yellow 24 | ..backgroundColor = Colors.green 25 | ..indicatorColor = Colors.yellow 26 | ..textColor = Colors.yellow 27 | ..maskColor = Colors.blue.withOpacity(0.5) 28 | ..userInteractions = true 29 | ..dismissOnTap = false 30 | ..customAnimation = CustomAnimation(); 31 | } 32 | 33 | class MyApp extends StatelessWidget { 34 | // This widget is the root of your application. 35 | @override 36 | Widget build(BuildContext context) { 37 | return MaterialApp( 38 | title: 'Flutter EasyLoading', 39 | theme: ThemeData( 40 | primarySwatch: Colors.blue, 41 | ), 42 | home: MyHomePage(title: 'Flutter EasyLoading'), 43 | builder: EasyLoading.init(), 44 | ); 45 | } 46 | } 47 | 48 | class MyHomePage extends StatefulWidget { 49 | MyHomePage({Key? key, this.title}) : super(key: key); 50 | 51 | final String? title; 52 | 53 | @override 54 | _MyHomePageState createState() => _MyHomePageState(); 55 | } 56 | 57 | class _MyHomePageState extends State { 58 | Timer? _timer; 59 | late double _progress; 60 | 61 | @override 62 | void initState() { 63 | super.initState(); 64 | EasyLoading.addStatusCallback((status) { 65 | print('EasyLoading Status $status'); 66 | if (status == EasyLoadingStatus.dismiss) { 67 | _timer?.cancel(); 68 | } 69 | }); 70 | EasyLoading.showSuccess('Use in initState'); 71 | // EasyLoading.removeCallbacks(); 72 | } 73 | 74 | @override 75 | Widget build(BuildContext context) { 76 | return Scaffold( 77 | appBar: AppBar( 78 | title: Text(widget.title ?? ''), 79 | ), 80 | body: Container( 81 | width: MediaQuery.of(context).size.width, 82 | child: SingleChildScrollView( 83 | child: Column( 84 | crossAxisAlignment: CrossAxisAlignment.center, 85 | mainAxisAlignment: MainAxisAlignment.start, 86 | children: [ 87 | TextField(), 88 | Wrap( 89 | runAlignment: WrapAlignment.center, 90 | crossAxisAlignment: WrapCrossAlignment.center, 91 | children: [ 92 | TextButton( 93 | child: Text('open test page'), 94 | onPressed: () { 95 | _timer?.cancel(); 96 | Navigator.push( 97 | context, 98 | MaterialPageRoute( 99 | builder: (BuildContext context) => TestPage(), 100 | ), 101 | ); 102 | }, 103 | ), 104 | TextButton( 105 | child: Text('dismiss'), 106 | onPressed: () async { 107 | _timer?.cancel(); 108 | await EasyLoading.dismiss(); 109 | print('EasyLoading dismiss'); 110 | }, 111 | ), 112 | TextButton( 113 | child: Text('show'), 114 | onPressed: () async { 115 | _timer?.cancel(); 116 | await EasyLoading.show( 117 | status: 'loading...', 118 | maskType: EasyLoadingMaskType.black, 119 | ); 120 | print('EasyLoading show'); 121 | }, 122 | ), 123 | TextButton( 124 | child: Text('showToast'), 125 | onPressed: () { 126 | _timer?.cancel(); 127 | EasyLoading.showToast( 128 | 'Toast', 129 | ); 130 | }, 131 | ), 132 | TextButton( 133 | child: Text('showSuccess'), 134 | onPressed: () async { 135 | _timer?.cancel(); 136 | await EasyLoading.showSuccess('Great Success!'); 137 | print('EasyLoading showSuccess'); 138 | }, 139 | ), 140 | TextButton( 141 | child: Text('showError'), 142 | onPressed: () { 143 | _timer?.cancel(); 144 | EasyLoading.showError('Failed with Error'); 145 | }, 146 | ), 147 | TextButton( 148 | child: Text('showInfo'), 149 | onPressed: () { 150 | _timer?.cancel(); 151 | EasyLoading.showInfo('Useful Information.'); 152 | }, 153 | ), 154 | TextButton( 155 | child: Text('showProgress'), 156 | onPressed: () { 157 | _progress = 0; 158 | _timer?.cancel(); 159 | _timer = Timer.periodic(const Duration(milliseconds: 100), 160 | (Timer timer) { 161 | EasyLoading.showProgress(_progress, 162 | status: '${(_progress * 100).toStringAsFixed(0)}%'); 163 | _progress += 0.03; 164 | 165 | if (_progress >= 1) { 166 | _timer?.cancel(); 167 | EasyLoading.dismiss(); 168 | } 169 | }); 170 | }, 171 | ), 172 | ], 173 | ), 174 | Padding( 175 | padding: EdgeInsets.only(top: 20.0), 176 | child: Column( 177 | children: [ 178 | Text('Style'), 179 | Padding( 180 | padding: EdgeInsets.only(top: 10.0), 181 | child: CupertinoSegmentedControl( 182 | selectedColor: Colors.blue, 183 | children: { 184 | EasyLoadingStyle.dark: Padding( 185 | padding: EdgeInsets.all(5.0), 186 | child: Text('dark'), 187 | ), 188 | EasyLoadingStyle.light: Padding( 189 | padding: EdgeInsets.all(5.0), 190 | child: Text('light'), 191 | ), 192 | EasyLoadingStyle.custom: Padding( 193 | padding: EdgeInsets.all(5.0), 194 | child: Text('custom'), 195 | ), 196 | }, 197 | onValueChanged: (value) { 198 | EasyLoading.instance.loadingStyle = value; 199 | }, 200 | ), 201 | ), 202 | ], 203 | ), 204 | ), 205 | Padding( 206 | padding: EdgeInsets.only(top: 20.0), 207 | child: Column( 208 | children: [ 209 | Text('MaskType'), 210 | Padding( 211 | padding: EdgeInsets.only(top: 10.0), 212 | child: CupertinoSegmentedControl( 213 | selectedColor: Colors.blue, 214 | children: { 215 | EasyLoadingMaskType.none: Padding( 216 | padding: EdgeInsets.all(5.0), 217 | child: Text('none'), 218 | ), 219 | EasyLoadingMaskType.clear: Padding( 220 | padding: EdgeInsets.all(5.0), 221 | child: Text('clear'), 222 | ), 223 | EasyLoadingMaskType.black: Padding( 224 | padding: EdgeInsets.all(5.0), 225 | child: Text('black'), 226 | ), 227 | EasyLoadingMaskType.custom: Padding( 228 | padding: EdgeInsets.all(5.0), 229 | child: Text('custom'), 230 | ), 231 | }, 232 | onValueChanged: (value) { 233 | EasyLoading.instance.maskType = value; 234 | }, 235 | ), 236 | ), 237 | ], 238 | ), 239 | ), 240 | Padding( 241 | padding: EdgeInsets.only(top: 20.0), 242 | child: Column( 243 | children: [ 244 | Text('Toast Positon'), 245 | Padding( 246 | padding: EdgeInsets.only(top: 10.0), 247 | child: 248 | CupertinoSegmentedControl( 249 | selectedColor: Colors.blue, 250 | children: { 251 | EasyLoadingToastPosition.top: Padding( 252 | padding: EdgeInsets.all(5.0), 253 | child: Text('top'), 254 | ), 255 | EasyLoadingToastPosition.center: Padding( 256 | padding: EdgeInsets.all(5.0), 257 | child: Text('center'), 258 | ), 259 | EasyLoadingToastPosition.bottom: Padding( 260 | padding: EdgeInsets.all(5.0), 261 | child: Text('bottom'), 262 | ), 263 | }, 264 | onValueChanged: (value) { 265 | EasyLoading.instance.toastPosition = value; 266 | }, 267 | ), 268 | ), 269 | ], 270 | ), 271 | ), 272 | Padding( 273 | padding: EdgeInsets.only(top: 20.0), 274 | child: Column( 275 | children: [ 276 | Text('Animation Style'), 277 | Padding( 278 | padding: EdgeInsets.only(top: 10.0), 279 | child: 280 | CupertinoSegmentedControl( 281 | selectedColor: Colors.blue, 282 | children: { 283 | EasyLoadingAnimationStyle.opacity: Padding( 284 | padding: EdgeInsets.all(5.0), 285 | child: Text('opacity'), 286 | ), 287 | EasyLoadingAnimationStyle.offset: Padding( 288 | padding: EdgeInsets.all(5.0), 289 | child: Text('offset'), 290 | ), 291 | EasyLoadingAnimationStyle.scale: Padding( 292 | padding: EdgeInsets.all(5.0), 293 | child: Text('scale'), 294 | ), 295 | EasyLoadingAnimationStyle.custom: Padding( 296 | padding: EdgeInsets.all(5.0), 297 | child: Text('custom'), 298 | ), 299 | }, 300 | onValueChanged: (value) { 301 | EasyLoading.instance.animationStyle = value; 302 | }, 303 | ), 304 | ), 305 | ], 306 | ), 307 | ), 308 | Padding( 309 | padding: EdgeInsets.only( 310 | top: 20.0, 311 | bottom: 50.0, 312 | ), 313 | child: Column( 314 | children: [ 315 | Text('IndicatorType(total: 23)'), 316 | Padding( 317 | padding: EdgeInsets.only(top: 10.0), 318 | child: 319 | CupertinoSegmentedControl( 320 | selectedColor: Colors.blue, 321 | children: { 322 | EasyLoadingIndicatorType.circle: Padding( 323 | padding: EdgeInsets.all(5.0), 324 | child: Text('circle'), 325 | ), 326 | EasyLoadingIndicatorType.wave: Padding( 327 | padding: EdgeInsets.all(5.0), 328 | child: Text('wave'), 329 | ), 330 | EasyLoadingIndicatorType.ring: Padding( 331 | padding: EdgeInsets.all(5.0), 332 | child: Text('ring'), 333 | ), 334 | EasyLoadingIndicatorType.pulse: Padding( 335 | padding: EdgeInsets.all(5.0), 336 | child: Text('pulse'), 337 | ), 338 | EasyLoadingIndicatorType.cubeGrid: Padding( 339 | padding: EdgeInsets.all(5.0), 340 | child: Text('cubeGrid'), 341 | ), 342 | EasyLoadingIndicatorType.threeBounce: Padding( 343 | padding: EdgeInsets.all(5.0), 344 | child: Text('threeBounce'), 345 | ), 346 | }, 347 | onValueChanged: (value) { 348 | EasyLoading.instance.indicatorType = value; 349 | }, 350 | ), 351 | ), 352 | ], 353 | ), 354 | ), 355 | ], 356 | ), 357 | ), 358 | ), 359 | ); 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /lib/src/easy_loading.dart: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2020 nslogx 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a 6 | // copy of this software and associated documentation files (the "Software"), 7 | // to deal in the Software without restriction, including without limitation 8 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | // and/or sell copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | 23 | import 'dart:async'; 24 | import 'dart:math'; 25 | 26 | import 'package:flutter/material.dart'; 27 | 28 | import './widgets/container.dart'; 29 | import './widgets/progress.dart'; 30 | import './widgets/indicator.dart'; 31 | import './widgets/overlay_entry.dart'; 32 | import './widgets/loading.dart'; 33 | import './animations/animation.dart'; 34 | import './theme.dart'; 35 | 36 | /// loading style 37 | enum EasyLoadingStyle { 38 | light, 39 | dark, 40 | custom, 41 | } 42 | 43 | /// toast position 44 | enum EasyLoadingToastPosition { 45 | top, 46 | center, 47 | bottom, 48 | } 49 | 50 | /// loading animation 51 | enum EasyLoadingAnimationStyle { 52 | opacity, 53 | offset, 54 | scale, 55 | custom, 56 | } 57 | 58 | /// loading mask type 59 | /// [none] default mask type, allow user interactions while loading is displayed 60 | /// [clear] don't allow user interactions while loading is displayed 61 | /// [black] don't allow user interactions while loading is displayed 62 | /// [custom] while mask type is custom, maskColor should not be null 63 | enum EasyLoadingMaskType { 64 | none, 65 | clear, 66 | black, 67 | custom, 68 | } 69 | 70 | /// loading indicator type. see [https://github.com/jogboms/flutter_spinkit#-showcase] 71 | enum EasyLoadingIndicatorType { 72 | fadingCircle, 73 | circle, 74 | threeBounce, 75 | chasingDots, 76 | wave, 77 | wanderingCubes, 78 | rotatingPlain, 79 | doubleBounce, 80 | fadingFour, 81 | fadingCube, 82 | pulse, 83 | cubeGrid, 84 | rotatingCircle, 85 | foldingCube, 86 | pumpingHeart, 87 | dualRing, 88 | hourGlass, 89 | pouringHourGlass, 90 | fadingGrid, 91 | ring, 92 | ripple, 93 | spinningCircle, 94 | squareCircle, 95 | } 96 | 97 | /// loading status 98 | enum EasyLoadingStatus { 99 | show, 100 | dismiss, 101 | } 102 | 103 | typedef EasyLoadingStatusCallback = void Function(EasyLoadingStatus status); 104 | 105 | class EasyLoading { 106 | /// loading style, default [EasyLoadingStyle.dark]. 107 | late EasyLoadingStyle loadingStyle; 108 | 109 | /// loading indicator type, default [EasyLoadingIndicatorType.fadingCircle]. 110 | late EasyLoadingIndicatorType indicatorType; 111 | 112 | /// loading mask type, default [EasyLoadingMaskType.none]. 113 | late EasyLoadingMaskType maskType; 114 | 115 | /// toast position, default [EasyLoadingToastPosition.center]. 116 | late EasyLoadingToastPosition toastPosition; 117 | 118 | /// loading animationStyle, default [EasyLoadingAnimationStyle.opacity]. 119 | late EasyLoadingAnimationStyle animationStyle; 120 | 121 | /// textAlign of status, default [TextAlign.center]. 122 | late TextAlign textAlign; 123 | 124 | /// content padding of loading. 125 | late EdgeInsets contentPadding; 126 | 127 | /// padding of [status]. 128 | late EdgeInsets textPadding; 129 | 130 | /// size of indicator, default 40.0. 131 | late double indicatorSize; 132 | 133 | /// radius of loading, default 5.0. 134 | late double radius; 135 | 136 | /// fontSize of loading, default 15.0. 137 | late double fontSize; 138 | 139 | /// width of progress indicator, default 2.0. 140 | late double progressWidth; 141 | 142 | /// width of indicator, default 4.0, only used for [EasyLoadingIndicatorType.ring, EasyLoadingIndicatorType.dualRing]. 143 | late double lineWidth; 144 | 145 | /// display duration of [showSuccess] [showError] [showInfo] [showToast], default 2000ms. 146 | late Duration displayDuration; 147 | 148 | /// animation duration of indicator, default 200ms. 149 | late Duration animationDuration; 150 | 151 | /// loading custom animation, default null. 152 | EasyLoadingAnimation? customAnimation; 153 | 154 | /// textStyle of status, default null. 155 | TextStyle? textStyle; 156 | 157 | /// color of loading status, only used for [EasyLoadingStyle.custom]. 158 | Color? textColor; 159 | 160 | /// color of loading indicator, only used for [EasyLoadingStyle.custom]. 161 | Color? indicatorColor; 162 | 163 | /// progress color of loading, only used for [EasyLoadingStyle.custom]. 164 | Color? progressColor; 165 | 166 | /// background color of loading, only used for [EasyLoadingStyle.custom]. 167 | Color? backgroundColor; 168 | 169 | /// boxShadow of loading, only used for [EasyLoadingStyle.custom]. 170 | List? boxShadow; 171 | 172 | /// mask color of loading, only used for [EasyLoadingMaskType.custom]. 173 | Color? maskColor; 174 | 175 | /// should allow user interactions while loading is displayed. 176 | bool? userInteractions; 177 | 178 | /// should dismiss on user tap. 179 | bool? dismissOnTap; 180 | 181 | /// indicator widget of loading 182 | Widget? indicatorWidget; 183 | 184 | /// success widget of loading 185 | Widget? successWidget; 186 | 187 | /// error widget of loading 188 | Widget? errorWidget; 189 | 190 | /// info widget of loading 191 | Widget? infoWidget; 192 | 193 | Widget? _w; 194 | 195 | EasyLoadingOverlayEntry? overlayEntry; 196 | GlobalKey? _key; 197 | GlobalKey? _progressKey; 198 | Timer? _timer; 199 | 200 | Widget? get w => _w; 201 | GlobalKey? get key => _key; 202 | GlobalKey? get progressKey => _progressKey; 203 | 204 | final List _statusCallbacks = 205 | []; 206 | 207 | factory EasyLoading() => _instance; 208 | static final EasyLoading _instance = EasyLoading._internal(); 209 | 210 | EasyLoading._internal() { 211 | /// set deafult value 212 | loadingStyle = EasyLoadingStyle.dark; 213 | indicatorType = EasyLoadingIndicatorType.fadingCircle; 214 | maskType = EasyLoadingMaskType.none; 215 | toastPosition = EasyLoadingToastPosition.center; 216 | animationStyle = EasyLoadingAnimationStyle.opacity; 217 | textAlign = TextAlign.center; 218 | indicatorSize = 40.0; 219 | radius = 5.0; 220 | fontSize = 15.0; 221 | progressWidth = 2.0; 222 | lineWidth = 4.0; 223 | displayDuration = const Duration(milliseconds: 2000); 224 | animationDuration = const Duration(milliseconds: 200); 225 | textPadding = const EdgeInsets.only(bottom: 10.0); 226 | contentPadding = const EdgeInsets.symmetric( 227 | vertical: 15.0, 228 | horizontal: 20.0, 229 | ); 230 | } 231 | 232 | static EasyLoading get instance => _instance; 233 | static bool get isShow => _instance.w != null; 234 | 235 | /// init EasyLoading 236 | static TransitionBuilder init({ 237 | TransitionBuilder? builder, 238 | }) { 239 | return (BuildContext context, Widget? child) { 240 | if (builder != null) { 241 | return builder(context, FlutterEasyLoading(child: child)); 242 | } else { 243 | return FlutterEasyLoading(child: child); 244 | } 245 | }; 246 | } 247 | 248 | /// show loading with [status] [indicator] [maskType] 249 | static Future show({ 250 | String? status, 251 | Widget? indicator, 252 | EasyLoadingMaskType? maskType, 253 | bool? dismissOnTap, 254 | }) { 255 | Widget w = indicator ?? (_instance.indicatorWidget ?? LoadingIndicator()); 256 | return _instance._show( 257 | status: status, 258 | maskType: maskType, 259 | dismissOnTap: dismissOnTap, 260 | w: w, 261 | ); 262 | } 263 | 264 | /// show progress with [value] [status] [maskType], value should be 0.0 ~ 1.0. 265 | static Future showProgress( 266 | double value, { 267 | String? status, 268 | EasyLoadingMaskType? maskType, 269 | }) async { 270 | assert( 271 | value >= 0.0 && value <= 1.0, 272 | 'progress value should be 0.0 ~ 1.0', 273 | ); 274 | 275 | if (_instance.loadingStyle == EasyLoadingStyle.custom) { 276 | assert( 277 | _instance.progressColor != null, 278 | 'while loading style is custom, progressColor should not be null', 279 | ); 280 | } 281 | 282 | if (_instance.w == null || _instance.progressKey == null) { 283 | if (_instance.key != null) await dismiss(animation: false); 284 | GlobalKey _progressKey = 285 | GlobalKey(); 286 | Widget w = EasyLoadingProgress( 287 | key: _progressKey, 288 | value: value, 289 | ); 290 | _instance._show( 291 | status: status, 292 | maskType: maskType, 293 | dismissOnTap: false, 294 | w: w, 295 | ); 296 | _instance._progressKey = _progressKey; 297 | } 298 | // update progress 299 | _instance.progressKey?.currentState?.updateProgress(min(1.0, value)); 300 | // update status 301 | if (status != null) _instance.key?.currentState?.updateStatus(status); 302 | } 303 | 304 | /// showSuccess [status] [duration] [maskType] 305 | static Future showSuccess( 306 | String status, { 307 | Duration? duration, 308 | EasyLoadingMaskType? maskType, 309 | bool? dismissOnTap, 310 | }) { 311 | Widget w = _instance.successWidget ?? 312 | Icon( 313 | Icons.done, 314 | color: EasyLoadingTheme.indicatorColor, 315 | size: EasyLoadingTheme.indicatorSize, 316 | ); 317 | return _instance._show( 318 | status: status, 319 | duration: duration ?? EasyLoadingTheme.displayDuration, 320 | maskType: maskType, 321 | dismissOnTap: dismissOnTap, 322 | w: w, 323 | ); 324 | } 325 | 326 | /// showError [status] [duration] [maskType] 327 | static Future showError( 328 | String status, { 329 | Duration? duration, 330 | EasyLoadingMaskType? maskType, 331 | bool? dismissOnTap, 332 | }) { 333 | Widget w = _instance.errorWidget ?? 334 | Icon( 335 | Icons.clear, 336 | color: EasyLoadingTheme.indicatorColor, 337 | size: EasyLoadingTheme.indicatorSize, 338 | ); 339 | return _instance._show( 340 | status: status, 341 | duration: duration ?? EasyLoadingTheme.displayDuration, 342 | maskType: maskType, 343 | dismissOnTap: dismissOnTap, 344 | w: w, 345 | ); 346 | } 347 | 348 | /// showInfo [status] [duration] [maskType] 349 | static Future showInfo( 350 | String status, { 351 | Duration? duration, 352 | EasyLoadingMaskType? maskType, 353 | bool? dismissOnTap, 354 | }) { 355 | Widget w = _instance.infoWidget ?? 356 | Icon( 357 | Icons.info_outline, 358 | color: EasyLoadingTheme.indicatorColor, 359 | size: EasyLoadingTheme.indicatorSize, 360 | ); 361 | return _instance._show( 362 | status: status, 363 | duration: duration ?? EasyLoadingTheme.displayDuration, 364 | maskType: maskType, 365 | dismissOnTap: dismissOnTap, 366 | w: w, 367 | ); 368 | } 369 | 370 | /// showToast [status] [duration] [toastPosition] [maskType] 371 | static Future showToast( 372 | String status, { 373 | Duration? duration, 374 | EasyLoadingToastPosition? toastPosition, 375 | EasyLoadingMaskType? maskType, 376 | bool? dismissOnTap, 377 | }) { 378 | return _instance._show( 379 | status: status, 380 | duration: duration ?? EasyLoadingTheme.displayDuration, 381 | toastPosition: toastPosition ?? EasyLoadingTheme.toastPosition, 382 | maskType: maskType, 383 | dismissOnTap: dismissOnTap, 384 | ); 385 | } 386 | 387 | /// dismiss loading 388 | static Future dismiss({ 389 | bool animation = true, 390 | }) { 391 | // cancel timer 392 | _instance._cancelTimer(); 393 | return _instance._dismiss(animation); 394 | } 395 | 396 | /// add loading status callback 397 | static void addStatusCallback(EasyLoadingStatusCallback callback) { 398 | if (!_instance._statusCallbacks.contains(callback)) { 399 | _instance._statusCallbacks.add(callback); 400 | } 401 | } 402 | 403 | /// remove single loading status callback 404 | static void removeCallback(EasyLoadingStatusCallback callback) { 405 | if (_instance._statusCallbacks.contains(callback)) { 406 | _instance._statusCallbacks.remove(callback); 407 | } 408 | } 409 | 410 | /// remove all loading status callback 411 | static void removeAllCallbacks() { 412 | _instance._statusCallbacks.clear(); 413 | } 414 | 415 | /// show [status] [duration] [toastPosition] [maskType] 416 | Future _show({ 417 | Widget? w, 418 | String? status, 419 | Duration? duration, 420 | EasyLoadingMaskType? maskType, 421 | bool? dismissOnTap, 422 | EasyLoadingToastPosition? toastPosition, 423 | }) async { 424 | assert( 425 | overlayEntry != null, 426 | 'You should call EasyLoading.init() in your MaterialApp', 427 | ); 428 | 429 | if (loadingStyle == EasyLoadingStyle.custom) { 430 | assert( 431 | backgroundColor != null, 432 | 'while loading style is custom, backgroundColor should not be null', 433 | ); 434 | assert( 435 | indicatorColor != null, 436 | 'while loading style is custom, indicatorColor should not be null', 437 | ); 438 | assert( 439 | textColor != null, 440 | 'while loading style is custom, textColor should not be null', 441 | ); 442 | } 443 | 444 | maskType ??= _instance.maskType; 445 | if (maskType == EasyLoadingMaskType.custom) { 446 | assert( 447 | maskColor != null, 448 | 'while mask type is custom, maskColor should not be null', 449 | ); 450 | } 451 | 452 | if (animationStyle == EasyLoadingAnimationStyle.custom) { 453 | assert( 454 | customAnimation != null, 455 | 'while animationStyle is custom, customAnimation should not be null', 456 | ); 457 | } 458 | 459 | toastPosition ??= EasyLoadingToastPosition.center; 460 | bool animation = _w == null; 461 | _progressKey = null; 462 | if (_key != null) await dismiss(animation: false); 463 | 464 | Completer completer = Completer(); 465 | _key = GlobalKey(); 466 | _w = EasyLoadingContainer( 467 | key: _key, 468 | status: status, 469 | indicator: w, 470 | animation: animation, 471 | toastPosition: toastPosition, 472 | maskType: maskType, 473 | dismissOnTap: dismissOnTap, 474 | completer: completer, 475 | ); 476 | completer.future.whenComplete(() { 477 | _callback(EasyLoadingStatus.show); 478 | if (duration != null) { 479 | _cancelTimer(); 480 | _timer = Timer(duration, () async { 481 | await dismiss(); 482 | }); 483 | } 484 | }); 485 | _markNeedsBuild(); 486 | return completer.future; 487 | } 488 | 489 | Future _dismiss(bool animation) async { 490 | if (key != null && key?.currentState == null) { 491 | _reset(); 492 | return; 493 | } 494 | 495 | return key?.currentState?.dismiss(animation).whenComplete(() { 496 | _reset(); 497 | }); 498 | } 499 | 500 | void _reset() { 501 | _w = null; 502 | _key = null; 503 | _progressKey = null; 504 | _cancelTimer(); 505 | _markNeedsBuild(); 506 | _callback(EasyLoadingStatus.dismiss); 507 | } 508 | 509 | void _callback(EasyLoadingStatus status) { 510 | for (final EasyLoadingStatusCallback callback in _statusCallbacks) { 511 | callback(status); 512 | } 513 | } 514 | 515 | void _markNeedsBuild() { 516 | overlayEntry?.markNeedsBuild(); 517 | } 518 | 519 | void _cancelTimer() { 520 | _timer?.cancel(); 521 | _timer = null; 522 | } 523 | } 524 | --------------------------------------------------------------------------------