├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android ├── .gitignore ├── build.gradle ├── gradle.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── vansz │ └── loading_indicator_view │ └── LoadingIndicatorViewPlugin.java ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── vansz │ │ │ │ │ └── loading_indicator_view_example │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── 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 │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── 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-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── main.m ├── lib │ └── main.dart ├── pubspec.yaml └── test │ └── widget_test.dart ├── flutter_indicator_view.gif ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── LoadingIndicatorViewPlugin.h │ └── LoadingIndicatorViewPlugin.m └── loading_indicator_view.podspec ├── lib ├── loading_indicator_view.dart └── src │ ├── indicators │ ├── ball_beat_indicator.dart │ ├── ball_clip_rotate_indicator.dart │ ├── ball_clip_rotate_multiple_indicator.dart │ ├── ball_clip_rotate_pulse_indicator.dart │ ├── ball_grid_beat_indicator.dart │ ├── ball_grid_pulse_indicator.dart │ ├── ball_pulse_indicator.dart │ ├── ball_pulse_rise_indicator.dart │ ├── ball_pulse_sync_indicator.dart │ ├── ball_rotate_indicator.dart │ ├── ball_scale_indicator.dart │ ├── ball_scale_multiple_indicator.dart │ ├── ball_scale_ripple_indicator.dart │ ├── ball_scale_ripple_multiple_indicator.dart │ ├── ball_spin_fade_loader_indicator.dart │ ├── ball_zig_zag_indicator.dart │ ├── cube_transition_indicator.dart │ ├── line_scale_indicator.dart │ ├── line_scale_pulse_out_indicator.dart │ ├── line_scale_pulse_out_rapid_indicator.dart │ ├── line_spin_fade_loader_indicator.dart │ ├── pacman_indicator.dart │ ├── semi_circle_spin_indicator.dart │ ├── square_spin_indicator.dart │ └── triangle_skew_spin_indicator.dart │ └── infinite_progress.dart ├── loading_indicator_view.iml ├── pubspec.yaml └── test └── loading_indicator_view_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | .idea/ 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | ios/.generated/ 9 | ios/Flutter/Generated.xcconfig 10 | ios/Runner/GeneratedPluginRegistrant.* 11 | pubspec.lock 12 | -------------------------------------------------------------------------------- /.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: bc7bc940836f1f834699625426795fd6f07c18ec 8 | channel: beta 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.1.0 2 | 3 | * 优化项目,去除无用代码,添加使用文档 4 | 5 | ## 1.0.0 6 | 7 | * 完成 24 个 loading widget 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # loading_indicator_view 2 | 3 | A collection of awesome flutter loading animation 4 | 5 | 6 | ## Demo 7 | 8 | 9 | 10 | ## Usage 11 | 12 | ``` 13 | loading_indicator_view: ^1.1.0 14 | ``` 15 | 16 | 17 | ## Animation types 18 | 19 | | Type | Type | Type | Type | 20 | |---|---|---|---| 21 | |1. LineSpinFadeLoader | 2. BallBeat | 3. BallClipRotateMultiple | 4. BallGridPulse | 22 | |5. LineScale | 6. BallPulseRise | 7. BallScaleRippleMultiple | 8. BallZigZag | 23 | |9. BallScale | 10. BallPulseSync| 11. BallScaleMultiple | 12. BallPulse | 24 | |13. BallClipRotatePulse | 14. BallGridBeat | 15. SquareSpin | 16. BallSpinFadeLoader | 25 | |17. BallScaleRipple | 18. SemiCircleSpin | 19. LineScalePulseOut | 20. BallClipRotate | 26 | |21. Pacman | 22. BallRotate | 23. CubeTransition | 24. TriangleSkewSpin| 27 | 28 | 29 | # Licence 30 | Copyright 2019 Hitomis, Inc. 31 | 32 | Licensed under the Apache License, Version 2.0 (the "License"); 33 | you may not use this file except in compliance with the License. 34 | You may obtain a copy of the License at 35 | 36 | http://www.apache.org/licenses/LICENSE-2.0 37 | 38 | Unless required by applicable law or agreed to in writing, software 39 | distributed under the License is distributed on an "AS IS" BASIS, 40 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 41 | See the License for the specific language governing permissions and 42 | limitations under the License. 43 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.vansz.loading_indicator_view' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.2.1' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 28 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 30 | } 31 | lintOptions { 32 | disable 'InvalidPackage' 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'loading_indicator_view' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/java/com/vansz/loading_indicator_view/LoadingIndicatorViewPlugin.java: -------------------------------------------------------------------------------- 1 | package com.vansz.loading_indicator_view; 2 | 3 | import io.flutter.plugin.common.MethodCall; 4 | import io.flutter.plugin.common.MethodChannel; 5 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 6 | import io.flutter.plugin.common.MethodChannel.Result; 7 | import io.flutter.plugin.common.PluginRegistry.Registrar; 8 | 9 | /** LoadingIndicatorViewPlugin */ 10 | public class LoadingIndicatorViewPlugin implements MethodCallHandler { 11 | /** Plugin registration. */ 12 | public static void registerWith(Registrar registrar) { 13 | final MethodChannel channel = new MethodChannel(registrar.messenger(), "loading_indicator_view"); 14 | channel.setMethodCallHandler(new LoadingIndicatorViewPlugin()); 15 | } 16 | 17 | @Override 18 | public void onMethodCall(MethodCall call, Result result) { 19 | if (call.method.equals("getPlatformVersion")) { 20 | result.success("Android " + android.os.Build.VERSION.RELEASE); 21 | } else { 22 | result.notImplemented(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /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 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /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 and should not be manually edited. 5 | 6 | version: 7 | revision: bc7bc940836f1f834699625426795fd6f07c18ec 8 | channel: beta 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | ## Example 2 | 3 | * LineSpinFadeLoaderIndicator(); 4 | * BallBeatIndicator(); 5 | * BallClipRotateMultipleIndicator(); 6 | * BallGridPulseIndicator(); 7 | * LineScaleIndicator(); 8 | * BallPulseRiseIndicator(); 9 | * BallScaleRippleMultipleIndicator(); 10 | * BallZigZagIndicator(); 11 | * BallScaleIndicator(); 12 | * BallPulseSyncIndicator(); 13 | * BallScaleMultipleIndicator(); 14 | * BallPulseIndicator(); 15 | * BallClipRotatePulseIndicator(); 16 | * BallGridBeatIndicator(); 17 | * SquareSpinIndicator(); 18 | * BallSpinFadeLoaderIndicator(); 19 | * BallScaleRippleIndicator(); 20 | * SemiCircleSpinIndicator(); 21 | * LineScalePulseOutIndicator(); 22 | * BallClipRotateIndicator(); 23 | * PacmanIndicator(); 24 | * BallRotateIndicator(); 25 | * CubeTransitionIndicator(); 26 | * TriangleSkewSpinIndicator(); 27 | 28 | ## details 29 | example/lib/main.dart -------------------------------------------------------------------------------- /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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.vansz.loading_indicator_view_example" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/vansz/loading_indicator_view_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.vansz.loading_indicator_view_example; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /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/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /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-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 37 | # referring to absolute paths on developers' machines. 38 | system('rm -rf .symlinks') 39 | system('mkdir -p .symlinks/plugins') 40 | 41 | # Flutter Pods 42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 43 | if generated_xcode_build_settings.empty? 44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first." 45 | end 46 | generated_xcode_build_settings.map { |p| 47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 48 | symlink = File.join('.symlinks', 'flutter') 49 | File.symlink(File.dirname(p[:path]), symlink) 50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 51 | end 52 | } 53 | 54 | # Plugin Pods 55 | plugin_pods = parse_KV_file('../.flutter-plugins') 56 | plugin_pods.map { |p| 57 | symlink = File.join('.symlinks', 'plugins', p[:name]) 58 | File.symlink(p[:path], symlink) 59 | pod p[:name], :path => File.join(symlink, 'ios') 60 | } 61 | end 62 | 63 | post_install do |installer| 64 | installer.pods_project.targets.each do |target| 65 | target.build_configurations.each do |config| 66 | config.build_settings['ENABLE_BITCODE'] = 'NO' 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 15 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 17 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 18 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 19 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 20 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 21 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXCopyFilesBuildPhase section */ 25 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 26 | isa = PBXCopyFilesBuildPhase; 27 | buildActionMask = 2147483647; 28 | dstPath = ""; 29 | dstSubfolderSpec = 10; 30 | files = ( 31 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 32 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 33 | ); 34 | name = "Embed Frameworks"; 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXCopyFilesBuildPhase section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 41 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 42 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 43 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 44 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 45 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 46 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 47 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 48 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 49 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 50 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 52 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 53 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 55 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 64 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 9740EEB11CF90186004384FC /* Flutter */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 3B80C3931E831B6300D905FE /* App.framework */, 75 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 76 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 77 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 78 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 79 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 80 | ); 81 | name = Flutter; 82 | sourceTree = ""; 83 | }; 84 | 97C146E51CF9000F007C117D = { 85 | isa = PBXGroup; 86 | children = ( 87 | 9740EEB11CF90186004384FC /* Flutter */, 88 | 97C146F01CF9000F007C117D /* Runner */, 89 | 97C146EF1CF9000F007C117D /* Products */, 90 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, 91 | ); 92 | sourceTree = ""; 93 | }; 94 | 97C146EF1CF9000F007C117D /* Products */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 97C146EE1CF9000F007C117D /* Runner.app */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | 97C146F01CF9000F007C117D /* Runner */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 106 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 107 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 108 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 109 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 110 | 97C147021CF9000F007C117D /* Info.plist */, 111 | 97C146F11CF9000F007C117D /* Supporting Files */, 112 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 113 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 114 | ); 115 | path = Runner; 116 | sourceTree = ""; 117 | }; 118 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 97C146F21CF9000F007C117D /* main.m */, 122 | ); 123 | name = "Supporting Files"; 124 | sourceTree = ""; 125 | }; 126 | /* End PBXGroup section */ 127 | 128 | /* Begin PBXNativeTarget section */ 129 | 97C146ED1CF9000F007C117D /* Runner */ = { 130 | isa = PBXNativeTarget; 131 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 132 | buildPhases = ( 133 | 9740EEB61CF901F6004384FC /* Run Script */, 134 | 97C146EA1CF9000F007C117D /* Sources */, 135 | 97C146EB1CF9000F007C117D /* Frameworks */, 136 | 97C146EC1CF9000F007C117D /* Resources */, 137 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 138 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 139 | ); 140 | buildRules = ( 141 | ); 142 | dependencies = ( 143 | ); 144 | name = Runner; 145 | productName = Runner; 146 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 147 | productType = "com.apple.product-type.application"; 148 | }; 149 | /* End PBXNativeTarget section */ 150 | 151 | /* Begin PBXProject section */ 152 | 97C146E61CF9000F007C117D /* Project object */ = { 153 | isa = PBXProject; 154 | attributes = { 155 | LastUpgradeCheck = 0910; 156 | ORGANIZATIONNAME = "The Chromium Authors"; 157 | TargetAttributes = { 158 | 97C146ED1CF9000F007C117D = { 159 | CreatedOnToolsVersion = 7.3.1; 160 | }; 161 | }; 162 | }; 163 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 164 | compatibilityVersion = "Xcode 3.2"; 165 | developmentRegion = English; 166 | hasScannedForEncodings = 0; 167 | knownRegions = ( 168 | en, 169 | Base, 170 | ); 171 | mainGroup = 97C146E51CF9000F007C117D; 172 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 173 | projectDirPath = ""; 174 | projectRoot = ""; 175 | targets = ( 176 | 97C146ED1CF9000F007C117D /* Runner */, 177 | ); 178 | }; 179 | /* End PBXProject section */ 180 | 181 | /* Begin PBXResourcesBuildPhase section */ 182 | 97C146EC1CF9000F007C117D /* Resources */ = { 183 | isa = PBXResourcesBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 187 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 188 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 189 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 190 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | /* End PBXResourcesBuildPhase section */ 195 | 196 | /* Begin PBXShellScriptBuildPhase section */ 197 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 198 | isa = PBXShellScriptBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | ); 202 | inputPaths = ( 203 | ); 204 | name = "Thin Binary"; 205 | outputPaths = ( 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | shellPath = /bin/sh; 209 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 210 | }; 211 | 9740EEB61CF901F6004384FC /* Run Script */ = { 212 | isa = PBXShellScriptBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | ); 216 | inputPaths = ( 217 | ); 218 | name = "Run Script"; 219 | outputPaths = ( 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | shellPath = /bin/sh; 223 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 224 | }; 225 | /* End PBXShellScriptBuildPhase section */ 226 | 227 | /* Begin PBXSourcesBuildPhase section */ 228 | 97C146EA1CF9000F007C117D /* Sources */ = { 229 | isa = PBXSourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 233 | 97C146F31CF9000F007C117D /* main.m in Sources */, 234 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | /* End PBXSourcesBuildPhase section */ 239 | 240 | /* Begin PBXVariantGroup section */ 241 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 242 | isa = PBXVariantGroup; 243 | children = ( 244 | 97C146FB1CF9000F007C117D /* Base */, 245 | ); 246 | name = Main.storyboard; 247 | sourceTree = ""; 248 | }; 249 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 250 | isa = PBXVariantGroup; 251 | children = ( 252 | 97C147001CF9000F007C117D /* Base */, 253 | ); 254 | name = LaunchScreen.storyboard; 255 | sourceTree = ""; 256 | }; 257 | /* End PBXVariantGroup section */ 258 | 259 | /* Begin XCBuildConfiguration section */ 260 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 261 | isa = XCBuildConfiguration; 262 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 263 | buildSettings = { 264 | ALWAYS_SEARCH_USER_PATHS = NO; 265 | CLANG_ANALYZER_NONNULL = YES; 266 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 267 | CLANG_CXX_LIBRARY = "libc++"; 268 | CLANG_ENABLE_MODULES = YES; 269 | CLANG_ENABLE_OBJC_ARC = YES; 270 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 271 | CLANG_WARN_BOOL_CONVERSION = YES; 272 | CLANG_WARN_COMMA = YES; 273 | CLANG_WARN_CONSTANT_CONVERSION = YES; 274 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 275 | CLANG_WARN_EMPTY_BODY = YES; 276 | CLANG_WARN_ENUM_CONVERSION = YES; 277 | CLANG_WARN_INFINITE_RECURSION = YES; 278 | CLANG_WARN_INT_CONVERSION = YES; 279 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 280 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 283 | CLANG_WARN_STRICT_PROTOTYPES = YES; 284 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 285 | CLANG_WARN_UNREACHABLE_CODE = YES; 286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 288 | COPY_PHASE_STRIP = NO; 289 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 290 | ENABLE_NS_ASSERTIONS = NO; 291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 292 | GCC_C_LANGUAGE_STANDARD = gnu99; 293 | GCC_NO_COMMON_BLOCKS = YES; 294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 296 | GCC_WARN_UNDECLARED_SELECTOR = YES; 297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 298 | GCC_WARN_UNUSED_FUNCTION = YES; 299 | GCC_WARN_UNUSED_VARIABLE = YES; 300 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 301 | MTL_ENABLE_DEBUG_INFO = NO; 302 | SDKROOT = iphoneos; 303 | TARGETED_DEVICE_FAMILY = "1,2"; 304 | VALIDATE_PRODUCT = YES; 305 | }; 306 | name = Profile; 307 | }; 308 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 309 | isa = XCBuildConfiguration; 310 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 311 | buildSettings = { 312 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 313 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 314 | DEVELOPMENT_TEAM = S8QB4VV633; 315 | ENABLE_BITCODE = NO; 316 | FRAMEWORK_SEARCH_PATHS = ( 317 | "$(inherited)", 318 | "$(PROJECT_DIR)/Flutter", 319 | ); 320 | INFOPLIST_FILE = Runner/Info.plist; 321 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 322 | LIBRARY_SEARCH_PATHS = ( 323 | "$(inherited)", 324 | "$(PROJECT_DIR)/Flutter", 325 | ); 326 | PRODUCT_BUNDLE_IDENTIFIER = com.vansz.loadingIndicatorViewExample; 327 | PRODUCT_NAME = "$(TARGET_NAME)"; 328 | VERSIONING_SYSTEM = "apple-generic"; 329 | }; 330 | name = Profile; 331 | }; 332 | 97C147031CF9000F007C117D /* Debug */ = { 333 | isa = XCBuildConfiguration; 334 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_ANALYZER_NONNULL = YES; 338 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 339 | CLANG_CXX_LIBRARY = "libc++"; 340 | CLANG_ENABLE_MODULES = YES; 341 | CLANG_ENABLE_OBJC_ARC = YES; 342 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 343 | CLANG_WARN_BOOL_CONVERSION = YES; 344 | CLANG_WARN_COMMA = YES; 345 | CLANG_WARN_CONSTANT_CONVERSION = YES; 346 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 347 | CLANG_WARN_EMPTY_BODY = YES; 348 | CLANG_WARN_ENUM_CONVERSION = YES; 349 | CLANG_WARN_INFINITE_RECURSION = YES; 350 | CLANG_WARN_INT_CONVERSION = YES; 351 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 352 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 353 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 354 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 355 | CLANG_WARN_STRICT_PROTOTYPES = YES; 356 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 357 | CLANG_WARN_UNREACHABLE_CODE = YES; 358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 359 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 360 | COPY_PHASE_STRIP = NO; 361 | DEBUG_INFORMATION_FORMAT = dwarf; 362 | ENABLE_STRICT_OBJC_MSGSEND = YES; 363 | ENABLE_TESTABILITY = YES; 364 | GCC_C_LANGUAGE_STANDARD = gnu99; 365 | GCC_DYNAMIC_NO_PIC = NO; 366 | GCC_NO_COMMON_BLOCKS = YES; 367 | GCC_OPTIMIZATION_LEVEL = 0; 368 | GCC_PREPROCESSOR_DEFINITIONS = ( 369 | "DEBUG=1", 370 | "$(inherited)", 371 | ); 372 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 373 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 374 | GCC_WARN_UNDECLARED_SELECTOR = YES; 375 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 376 | GCC_WARN_UNUSED_FUNCTION = YES; 377 | GCC_WARN_UNUSED_VARIABLE = YES; 378 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 379 | MTL_ENABLE_DEBUG_INFO = YES; 380 | ONLY_ACTIVE_ARCH = YES; 381 | SDKROOT = iphoneos; 382 | TARGETED_DEVICE_FAMILY = "1,2"; 383 | }; 384 | name = Debug; 385 | }; 386 | 97C147041CF9000F007C117D /* Release */ = { 387 | isa = XCBuildConfiguration; 388 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 397 | CLANG_WARN_BOOL_CONVERSION = YES; 398 | CLANG_WARN_COMMA = YES; 399 | CLANG_WARN_CONSTANT_CONVERSION = YES; 400 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 401 | CLANG_WARN_EMPTY_BODY = YES; 402 | CLANG_WARN_ENUM_CONVERSION = YES; 403 | CLANG_WARN_INFINITE_RECURSION = YES; 404 | CLANG_WARN_INT_CONVERSION = YES; 405 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 406 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 407 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 408 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 409 | CLANG_WARN_STRICT_PROTOTYPES = YES; 410 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 411 | CLANG_WARN_UNREACHABLE_CODE = YES; 412 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 413 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 414 | COPY_PHASE_STRIP = NO; 415 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 416 | ENABLE_NS_ASSERTIONS = NO; 417 | ENABLE_STRICT_OBJC_MSGSEND = YES; 418 | GCC_C_LANGUAGE_STANDARD = gnu99; 419 | GCC_NO_COMMON_BLOCKS = YES; 420 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 421 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 422 | GCC_WARN_UNDECLARED_SELECTOR = YES; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 427 | MTL_ENABLE_DEBUG_INFO = NO; 428 | SDKROOT = iphoneos; 429 | TARGETED_DEVICE_FAMILY = "1,2"; 430 | VALIDATE_PRODUCT = YES; 431 | }; 432 | name = Release; 433 | }; 434 | 97C147061CF9000F007C117D /* Debug */ = { 435 | isa = XCBuildConfiguration; 436 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 437 | buildSettings = { 438 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 439 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 440 | ENABLE_BITCODE = NO; 441 | FRAMEWORK_SEARCH_PATHS = ( 442 | "$(inherited)", 443 | "$(PROJECT_DIR)/Flutter", 444 | ); 445 | INFOPLIST_FILE = Runner/Info.plist; 446 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 447 | LIBRARY_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "$(PROJECT_DIR)/Flutter", 450 | ); 451 | PRODUCT_BUNDLE_IDENTIFIER = com.vansz.loadingIndicatorViewExample; 452 | PRODUCT_NAME = "$(TARGET_NAME)"; 453 | VERSIONING_SYSTEM = "apple-generic"; 454 | }; 455 | name = Debug; 456 | }; 457 | 97C147071CF9000F007C117D /* Release */ = { 458 | isa = XCBuildConfiguration; 459 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 460 | buildSettings = { 461 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 462 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 463 | ENABLE_BITCODE = NO; 464 | FRAMEWORK_SEARCH_PATHS = ( 465 | "$(inherited)", 466 | "$(PROJECT_DIR)/Flutter", 467 | ); 468 | INFOPLIST_FILE = Runner/Info.plist; 469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 470 | LIBRARY_SEARCH_PATHS = ( 471 | "$(inherited)", 472 | "$(PROJECT_DIR)/Flutter", 473 | ); 474 | PRODUCT_BUNDLE_IDENTIFIER = com.vansz.loadingIndicatorViewExample; 475 | PRODUCT_NAME = "$(TARGET_NAME)"; 476 | VERSIONING_SYSTEM = "apple-generic"; 477 | }; 478 | name = Release; 479 | }; 480 | /* End XCBuildConfiguration section */ 481 | 482 | /* Begin XCConfigurationList section */ 483 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 484 | isa = XCConfigurationList; 485 | buildConfigurations = ( 486 | 97C147031CF9000F007C117D /* Debug */, 487 | 97C147041CF9000F007C117D /* Release */, 488 | 249021D3217E4FDB00AE95B9 /* Profile */, 489 | ); 490 | defaultConfigurationIsVisible = 0; 491 | defaultConfigurationName = Release; 492 | }; 493 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 494 | isa = XCConfigurationList; 495 | buildConfigurations = ( 496 | 97C147061CF9000F007C117D /* Debug */, 497 | 97C147071CF9000F007C117D /* Release */, 498 | 249021D4217E4FDB00AE95B9 /* Profile */, 499 | ); 500 | defaultConfigurationIsVisible = 0; 501 | defaultConfigurationName = Release; 502 | }; 503 | /* End XCConfigurationList section */ 504 | }; 505 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 506 | } 507 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /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/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/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/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | loading_indicator_view_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:loading_indicator_view/loading_indicator_view.dart'; 4 | 5 | void main() => runApp(MyApp()); 6 | 7 | class MyApp extends StatelessWidget { 8 | // This widget is the root of your application. 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'Flutter Demo', 13 | debugShowCheckedModeBanner: false, 14 | theme: ThemeData( 15 | // This is the theme of your application. 16 | // 17 | // Try running your application with "flutter run". You'll see the 18 | // application has a blue toolbar. Then, without quitting the app, try 19 | // changing the primarySwatch below to Colors.green and then invoke 20 | // "hot reload" (press "r" in the console where you ran "flutter run", 21 | // or simply save your changes to "hot reload" in a Flutter IDE). 22 | // Notice that the counter didn't reset back to zero; the application 23 | // is not restarted. 24 | primarySwatch: Colors.blue, 25 | ), 26 | home: MyHomePage(title: 'Flutter Demo Home Page'), 27 | ); 28 | } 29 | } 30 | 31 | class MyHomePage extends StatefulWidget { 32 | MyHomePage({Key key, this.title}) : super(key: key); 33 | 34 | final String title; 35 | 36 | @override 37 | _MyHomePageState createState() => _MyHomePageState(); 38 | } 39 | 40 | class _MyHomePageState extends State { 41 | int _orderNum = 1; 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Scaffold( 46 | backgroundColor: Color.fromARGB(255, 185, 63, 81), 47 | body: GridView( 48 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 49 | crossAxisCount: 4, 50 | childAspectRatio: 1.0, 51 | ), 52 | children: [ 53 | wrapOrder(Center(child: LineSpinFadeLoaderIndicator())), 54 | wrapOrder(Center(child: BallBeatIndicator())), 55 | wrapOrder(Center(child: BallClipRotateMultipleIndicator())), 56 | wrapOrder(Center(child: BallGridPulseIndicator())), 57 | wrapOrder(Center(child: LineScaleIndicator())), 58 | wrapOrder(Center(child: BallPulseRiseIndicator())), 59 | wrapOrder(Center(child: BallScaleRippleMultipleIndicator())), 60 | wrapOrder(Center(child: BallZigZagIndicator())), 61 | wrapOrder(Center(child: BallScaleIndicator())), 62 | wrapOrder(Center(child: BallPulseSyncIndicator())), 63 | wrapOrder(Center(child: BallScaleMultipleIndicator())), 64 | wrapOrder(Center(child: BallPulseIndicator())), 65 | wrapOrder(Center(child: BallClipRotatePulseIndicator())), 66 | wrapOrder(Center(child: BallGridBeatIndicator())), 67 | wrapOrder(Center(child: SquareSpinIndicator())), 68 | wrapOrder(Center(child: BallSpinFadeLoaderIndicator())), 69 | wrapOrder(Center(child: BallScaleRippleIndicator())), 70 | wrapOrder(Center(child: SemiCircleSpinIndicator())), 71 | wrapOrder(Center(child: LineScalePulseOutIndicator())), 72 | wrapOrder(Center(child: BallClipRotateIndicator())), 73 | wrapOrder(Center(child: PacmanIndicator())), 74 | wrapOrder(Center(child: BallRotateIndicator())), 75 | wrapOrder(Center(child: CubeTransitionIndicator())), 76 | wrapOrder(Center(child: TriangleSkewSpinIndicator())), 77 | ], 78 | ), 79 | ); 80 | } 81 | 82 | 83 | @override 84 | void didUpdateWidget(MyHomePage oldWidget) { 85 | super.didUpdateWidget(oldWidget); 86 | if (oldWidget != widget) { 87 | _orderNum = 1; 88 | } 89 | } 90 | 91 | Widget wrapContainer(Widget child, [Color backgroundColor = Colors.green]) => 92 | Container(color: backgroundColor, child: child); 93 | 94 | Widget wrapOrder(Widget child) => Stack(children: [ 95 | child, 96 | Positioned( 97 | left: 8, 98 | bottom: 0, 99 | child: Text("${_orderNum++}", 100 | style: TextStyle(color: Colors.white, fontSize: 18)), 101 | ), 102 | ]); 103 | } 104 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: loading_indicator_view_example 2 | description: Demonstrates how to use the loading_indicator_view plugin. 3 | publish_to: 'none' 4 | 5 | environment: 6 | sdk: ">=2.1.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | 12 | # The following adds the Cupertino Icons font to your application. 13 | # Use with the CupertinoIcons class for iOS style icons. 14 | cupertino_icons: ^0.1.2 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | loading_indicator_view: 21 | path: ../ 22 | 23 | # For information on the generic Dart part of this file, see the 24 | # following page: https://dart.dev/tools/pub/pubspec 25 | 26 | # The following section is specific to Flutter. 27 | flutter: 28 | 29 | # The following line ensures that the Material Icons font is 30 | # included with your application, so that you can use the icons in 31 | # the material Icons class. 32 | uses-material-design: true 33 | 34 | # To add assets to your application, add an assets section, like this: 35 | # assets: 36 | # - images/a_dot_burr.jpeg 37 | # - images/a_dot_ham.jpeg 38 | 39 | # An image asset can refer to one or more resolution-specific "variants", see 40 | # https://flutter.dev/assets-and-images/#resolution-aware. 41 | 42 | # For details regarding adding assets from package dependencies, see 43 | # https://flutter.dev/assets-and-images/#from-packages 44 | 45 | # To add custom fonts to your application, add a fonts section here, 46 | # in this "flutter" section. Each entry in this list should have a 47 | # "family" key with the font family name, and a "fonts" key with a 48 | # list giving the asset and other descriptors for the font. For 49 | # example: 50 | # fonts: 51 | # - family: Schyler 52 | # fonts: 53 | # - asset: fonts/Schyler-Regular.ttf 54 | # - asset: fonts/Schyler-Italic.ttf 55 | # style: italic 56 | # - family: Trajan Pro 57 | # fonts: 58 | # - asset: fonts/TrajanPro.ttf 59 | # - asset: fonts/TrajanPro_Bold.ttf 60 | # weight: 700 61 | # 62 | # For details regarding fonts from package dependencies, 63 | # see https://flutter.dev/custom-fonts/#from-packages 64 | -------------------------------------------------------------------------------- /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_test/flutter_test.dart'; 9 | 10 | 11 | void main() { 12 | testWidgets('Verify Platform version', (WidgetTester tester) async { 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /flutter_indicator_view.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/flutter_indicator_view.gif -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hitomis/loading_indicator_view/08082fdfca2efadf0b3465522a0711bc99a2ed70/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/LoadingIndicatorViewPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface LoadingIndicatorViewPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/LoadingIndicatorViewPlugin.m: -------------------------------------------------------------------------------- 1 | #import "LoadingIndicatorViewPlugin.h" 2 | 3 | @implementation LoadingIndicatorViewPlugin 4 | + (void)registerWithRegistrar:(NSObject*)registrar { 5 | FlutterMethodChannel* channel = [FlutterMethodChannel 6 | methodChannelWithName:@"loading_indicator_view" 7 | binaryMessenger:[registrar messenger]]; 8 | LoadingIndicatorViewPlugin* instance = [[LoadingIndicatorViewPlugin alloc] init]; 9 | [registrar addMethodCallDelegate:instance channel:channel]; 10 | } 11 | 12 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 13 | if ([@"getPlatformVersion" isEqualToString:call.method]) { 14 | result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); 15 | } else { 16 | result(FlutterMethodNotImplemented); 17 | } 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ios/loading_indicator_view.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'loading_indicator_view' 6 | s.version = '0.0.1' 7 | s.summary = 'Flutter loading indicator widget' 8 | s.description = <<-DESC 9 | Flutter loading indicator widget 10 | DESC 11 | s.homepage = 'http://example.com' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'email@example.com' } 14 | s.source = { :path => '.' } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | 19 | s.ios.deployment_target = '8.0' 20 | end 21 | 22 | -------------------------------------------------------------------------------- /lib/loading_indicator_view.dart: -------------------------------------------------------------------------------- 1 | export 'src/indicators/ball_beat_indicator.dart'; 2 | export 'src/indicators/ball_clip_rotate_indicator.dart'; 3 | export 'src/indicators/ball_clip_rotate_multiple_indicator.dart'; 4 | export 'src/indicators/ball_clip_rotate_pulse_indicator.dart'; 5 | export 'src/indicators/ball_grid_beat_indicator.dart'; 6 | export 'src/indicators/ball_grid_pulse_indicator.dart'; 7 | export 'src/indicators/ball_pulse_indicator.dart'; 8 | export 'src/indicators/ball_pulse_rise_indicator.dart'; 9 | export 'src/indicators/ball_pulse_sync_indicator.dart'; 10 | export 'src/indicators/ball_rotate_indicator.dart'; 11 | export 'src/indicators/ball_scale_indicator.dart'; 12 | export 'src/indicators/ball_scale_multiple_indicator.dart'; 13 | export 'src/indicators/ball_scale_ripple_indicator.dart'; 14 | export 'src/indicators/ball_scale_ripple_multiple_indicator.dart'; 15 | export 'src/indicators/ball_spin_fade_loader_indicator.dart'; 16 | export 'src/indicators/ball_zig_zag_indicator.dart'; 17 | export 'src/indicators/cube_transition_indicator.dart'; 18 | export 'src/indicators/line_scale_indicator.dart'; 19 | export 'src/indicators/line_scale_pulse_out_indicator.dart'; 20 | export 'src/indicators/line_scale_pulse_out_rapid_indicator.dart'; 21 | export 'src/indicators/line_spin_fade_loader_indicator.dart'; 22 | export 'src/indicators/pacman_indicator.dart'; 23 | export 'src/indicators/semi_circle_spin_indicator.dart'; 24 | export 'src/indicators/square_spin_indicator.dart'; 25 | export 'src/indicators/triangle_skew_spin_indicator.dart'; 26 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_beat_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author: Vans Z 8 | /// date: 2019-05-31 9 | /// 10 | 11 | class BallBeatIndicator extends StatefulWidget { 12 | BallBeatIndicator({ 13 | this.minAlpha: 51, 14 | this.maxAlpha: 255, 15 | this.minRadius: 5.6, 16 | this.maxRadius: 7.2, 17 | this.spacing: 3, 18 | this.ballColor: Colors.white, 19 | this.duration: const Duration(milliseconds: 400), 20 | }); 21 | 22 | final int minAlpha; 23 | final int maxAlpha; 24 | final double minRadius; 25 | final double maxRadius; 26 | final double spacing; 27 | final Color ballColor; 28 | final Duration duration; 29 | 30 | @override 31 | State createState() => _BallBeatIndicatorState(); 32 | } 33 | 34 | class _BallBeatIndicatorState extends State 35 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 36 | @override 37 | void initState() { 38 | startEngine(this, widget.duration); 39 | super.initState(); 40 | } 41 | 42 | @override 43 | void dispose() { 44 | closeEngine(); 45 | super.dispose(); 46 | } 47 | 48 | @override 49 | Size measureSize() { 50 | var width = widget.maxRadius * 2 * 3 + widget.spacing * 2; 51 | var height = widget.maxRadius * 2; 52 | return Size(width, height); 53 | } 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | return AnimatedBuilder( 58 | animation: controller, 59 | builder: (context, child) { 60 | return CustomPaint( 61 | size: measureSize(), 62 | painter: _BallBeatIndicatorPainter( 63 | animationValue: animationValue, 64 | minRadius: widget.minRadius, 65 | maxRadius: widget.maxRadius, 66 | minAlpha: widget.minAlpha, 67 | maxAlpha: widget.maxAlpha, 68 | spacing: widget.spacing, 69 | ballColor: widget.ballColor, 70 | ), 71 | ); 72 | }, 73 | ); 74 | } 75 | } 76 | 77 | double progress = .0; 78 | double lastExtent = .0; 79 | 80 | class _BallBeatIndicatorPainter extends CustomPainter { 81 | _BallBeatIndicatorPainter({ 82 | this.animationValue, 83 | this.minRadius, 84 | this.maxRadius, 85 | this.minAlpha, 86 | this.maxAlpha, 87 | this.spacing, 88 | this.ballColor, 89 | }) : alphaList = [ 90 | minAlpha + (maxAlpha - minAlpha) * 0.9, 91 | minAlpha + (maxAlpha - minAlpha) * 0.1, 92 | minAlpha + (maxAlpha - minAlpha) * 0.9, 93 | ], 94 | radiusList = [ 95 | minRadius + (maxRadius - minRadius) * 0.9, 96 | minRadius + (maxRadius - minRadius) * 0.63, 97 | minRadius + (maxRadius - minRadius) * 0.9, 98 | ]; 99 | 100 | final double animationValue; 101 | final double minRadius; 102 | final double maxRadius; 103 | final int minAlpha; 104 | final int maxAlpha; 105 | final double spacing; 106 | final Color ballColor; 107 | final List alphaList; 108 | final List radiusList; 109 | 110 | @override 111 | void paint(Canvas canvas, Size size) { 112 | var paint = Paint() 113 | ..isAntiAlias = true 114 | ..style = PaintingStyle.fill 115 | ..strokeJoin = StrokeJoin.round 116 | ..strokeCap = StrokeCap.round; 117 | 118 | progress += (lastExtent - animationValue).abs(); 119 | lastExtent = animationValue; 120 | if (progress >= double.maxFinite) { 121 | progress = .0; 122 | lastExtent = .0; 123 | } 124 | 125 | var diffAlpha = maxAlpha - minAlpha; 126 | var diffRadius = maxRadius - minRadius; 127 | for (int i = 0; i < radiusList.length; i++) { 128 | var offsetAlpha = asin((alphaList[i] - minAlpha) / diffAlpha); 129 | var beatAlpha = 130 | sin(progress * pi / 180 + offsetAlpha).abs() * diffAlpha + minAlpha; 131 | paint.color = Color.fromARGB( 132 | beatAlpha.round(), ballColor.red, ballColor.green, ballColor.blue); 133 | 134 | var dx = maxRadius + 2 * i * maxRadius + i * spacing; 135 | var offset = Offset(dx, maxRadius); 136 | var offsetExtent = asin((radiusList[i] - minRadius) / diffRadius); 137 | var scaleRadius = 138 | sin(progress * pi / 180 + offsetExtent).abs() * diffRadius + 139 | minRadius; 140 | canvas.drawCircle(offset, scaleRadius, paint); 141 | } 142 | } 143 | 144 | @override 145 | bool shouldRepaint(CustomPainter oldDelegate) => true; 146 | } 147 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_clip_rotate_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-04 8 | /// 9 | 10 | class BallClipRotateIndicator extends StatefulWidget { 11 | BallClipRotateIndicator({ 12 | this.startAngle: -5, 13 | this.minRadius: 12, 14 | this.maxRadius: 20, 15 | this.color: Colors.white, 16 | this.duration: const Duration(milliseconds: 400), 17 | }); 18 | 19 | final double startAngle; 20 | final double minRadius; 21 | final double maxRadius; 22 | final Color color; 23 | final Duration duration; 24 | 25 | @override 26 | State createState() => _BallClipRotateIndicatorState(); 27 | } 28 | 29 | class _BallClipRotateIndicatorState extends State 30 | with SingleTickerProviderStateMixin { 31 | Animation _radius; 32 | Animation _rotate; 33 | AnimationController _controller; 34 | 35 | @override 36 | void initState() { 37 | _controller = AnimationController(duration: widget.duration, vsync: this); 38 | _radius = 39 | Tween(begin: widget.minRadius, end: widget.maxRadius).animate( 40 | CurvedAnimation( 41 | parent: _controller, 42 | curve: Interval(0, 1, curve: Curves.fastOutSlowIn), 43 | ), 44 | ); 45 | _rotate = Tween( 46 | begin: 0, 47 | end: 360, 48 | ).animate( 49 | CurvedAnimation( 50 | parent: _controller, 51 | curve: Interval(0, 1, curve: Curves.fastOutSlowIn), 52 | ), 53 | ); 54 | _controller.addStatusListener((AnimationStatus status) { 55 | if (status == AnimationStatus.completed) { 56 | _controller.reverse(); 57 | } else if (status == AnimationStatus.dismissed) { 58 | _controller.forward(); 59 | } 60 | }); 61 | _controller.forward(); 62 | super.initState(); 63 | } 64 | 65 | @override 66 | void dispose() { 67 | _controller?.dispose(); 68 | super.dispose(); 69 | } 70 | 71 | Size _measureSize() { 72 | return Size(2 * widget.maxRadius, 2 * widget.maxRadius); 73 | } 74 | 75 | @override 76 | Widget build(BuildContext context) { 77 | return AnimatedBuilder( 78 | animation: _controller, 79 | builder: (context, child) { 80 | return CustomPaint( 81 | size: _measureSize(), 82 | painter: _BallClipRotateIndicatorPainter( 83 | angle: _rotate.value, 84 | radius: _radius.value, 85 | startAngle: widget.startAngle, 86 | minRadius: widget.minRadius, 87 | maxRadius: widget.maxRadius, 88 | color: widget.color, 89 | ), 90 | ); 91 | }, 92 | ); 93 | } 94 | } 95 | 96 | double _progress = .0; 97 | double _lastExtent = .0; 98 | 99 | class _BallClipRotateIndicatorPainter extends CustomPainter { 100 | _BallClipRotateIndicatorPainter({ 101 | this.angle, 102 | this.radius, 103 | this.minRadius, 104 | this.maxRadius, 105 | this.startAngle, 106 | this.color, 107 | }); 108 | 109 | final double angle; 110 | final double radius; 111 | final double minRadius; 112 | final double maxRadius; 113 | final double startAngle; 114 | final Color color; 115 | 116 | @override 117 | void paint(Canvas canvas, Size size) { 118 | var paint = Paint() 119 | ..isAntiAlias = true 120 | ..style = PaintingStyle.stroke 121 | ..strokeWidth = 2 122 | ..strokeCap = StrokeCap.round 123 | ..color = color; 124 | 125 | _progress += (_lastExtent - angle).abs(); 126 | _lastExtent = angle; 127 | if (_progress >= double.maxFinite) { 128 | _progress = .0; 129 | _lastExtent = .0; 130 | } 131 | 132 | canvas.translate(size.width * .5, size.height * .5); 133 | canvas.rotate((_progress + startAngle) * pi / 180); 134 | var preScale = minRadius / maxRadius; 135 | var scale = preScale + (radius - minRadius) / maxRadius; 136 | canvas.scale(scale); 137 | Rect rect = Rect.fromLTWH( 138 | -size.width * .5, -size.height * .5, size.width, size.height); 139 | canvas.drawArc(rect, -45 * pi / 180, 270 * pi / 180, false, paint); 140 | } 141 | 142 | @override 143 | bool shouldRepaint(CustomPainter oldDelegate) => true; 144 | } 145 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_clip_rotate_multiple_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-05 8 | /// 9 | 10 | class BallClipRotateMultipleIndicator extends StatefulWidget { 11 | BallClipRotateMultipleIndicator({ 12 | this.startAngle: 0, 13 | this.minRadius: 10, 14 | this.maxRadius: 20, 15 | this.dashCircleRadius: 10, 16 | this.color: Colors.white, 17 | this.duration: const Duration(milliseconds: 400), 18 | }); 19 | 20 | final double startAngle; 21 | final double minRadius; 22 | final double maxRadius; 23 | final double dashCircleRadius; 24 | final Color color; 25 | final Duration duration; 26 | 27 | @override 28 | State createState() => _BallClipRotateMultipleIndicator(); 29 | } 30 | 31 | class _BallClipRotateMultipleIndicator 32 | extends State 33 | with SingleTickerProviderStateMixin { 34 | Animation _radius; 35 | Animation _rotate; 36 | AnimationController _controller; 37 | 38 | @override 39 | void initState() { 40 | _controller = AnimationController(duration: widget.duration, vsync: this); 41 | _radius = 42 | Tween(begin: widget.minRadius, end: widget.maxRadius).animate( 43 | CurvedAnimation( 44 | parent: _controller, 45 | curve: Interval(0, 1, curve: Curves.fastOutSlowIn), 46 | ), 47 | ); 48 | _rotate = Tween( 49 | begin: 0, 50 | end: 180, 51 | ).animate( 52 | CurvedAnimation( 53 | parent: _controller, 54 | curve: Interval(0, 1, curve: Curves.fastOutSlowIn), 55 | ), 56 | ); 57 | _controller.addStatusListener((AnimationStatus status) { 58 | if (status == AnimationStatus.completed) { 59 | _controller.reverse(); 60 | } else if (status == AnimationStatus.dismissed) { 61 | _controller.forward(); 62 | } 63 | }); 64 | _controller.forward(); 65 | super.initState(); 66 | } 67 | 68 | @override 69 | void dispose() { 70 | _controller?.dispose(); 71 | super.dispose(); 72 | } 73 | 74 | Size _measureSize() { 75 | return Size(2 * widget.maxRadius, 2 * widget.maxRadius); 76 | } 77 | 78 | @override 79 | Widget build(BuildContext context) { 80 | return AnimatedBuilder( 81 | animation: _controller, 82 | builder: (context, child) { 83 | return CustomPaint( 84 | size: _measureSize(), 85 | painter: _BallClipRotateMultipleIndicatorPainter( 86 | angle: _rotate.value, 87 | radius: _radius.value, 88 | minRadius: widget.minRadius, 89 | maxRadius: widget.maxRadius, 90 | dashCircleRadius: widget.dashCircleRadius, 91 | startAngle: widget.startAngle, 92 | color: widget.color, 93 | ), 94 | ); 95 | }, 96 | ); 97 | } 98 | } 99 | 100 | double _progress = .0; 101 | double _lastExtent = .0; 102 | 103 | class _BallClipRotateMultipleIndicatorPainter extends CustomPainter { 104 | _BallClipRotateMultipleIndicatorPainter({ 105 | this.angle, 106 | this.radius, 107 | this.minRadius, 108 | this.maxRadius, 109 | this.dashCircleRadius, 110 | this.startAngle, 111 | this.color, 112 | }) : outsideStartAngles = [135, -45], 113 | insideStartAngles = [225, 45]; 114 | 115 | final double angle; 116 | final double radius; 117 | final double minRadius; 118 | final double maxRadius; 119 | final double dashCircleRadius; 120 | final double startAngle; 121 | final List outsideStartAngles; 122 | final List insideStartAngles; 123 | final Color color; 124 | 125 | @override 126 | void paint(Canvas canvas, Size size) { 127 | var paint = Paint() 128 | ..isAntiAlias = true 129 | ..style = PaintingStyle.stroke 130 | ..strokeCap = StrokeCap.round 131 | ..strokeWidth = 2 132 | ..color = color; 133 | 134 | _progress += (_lastExtent - angle).abs(); 135 | _lastExtent = angle; 136 | if (_progress >= double.maxFinite) { 137 | _progress = .0; 138 | _lastExtent = .0; 139 | } 140 | 141 | var halfWidth = size.width * .5; 142 | var halfHeight = size.height * .5; 143 | 144 | canvas.save(); 145 | canvas.translate(halfWidth, halfHeight); 146 | canvas.rotate((_progress + startAngle) * pi / 180); 147 | var preScale = minRadius / maxRadius; 148 | var scale = preScale + (radius - minRadius) / maxRadius; 149 | canvas.scale(scale); 150 | 151 | for (var i = 0; i < outsideStartAngles.length; i++) { 152 | Rect rect = 153 | Rect.fromLTWH(-halfWidth, -halfHeight, size.width, size.height); 154 | canvas.drawArc( 155 | rect, outsideStartAngles[i] * pi / 180, 90 * pi / 180, false, paint); 156 | } 157 | canvas.restore(); 158 | 159 | canvas.save(); 160 | var dashCircleSize = dashCircleRadius * 2; 161 | canvas.translate(halfWidth, halfHeight); 162 | canvas.rotate((-_progress + startAngle) * pi / 180); 163 | canvas.scale(scale); 164 | for (var i = 0; i < insideStartAngles.length; i++) { 165 | Rect rect = Rect.fromLTWH( 166 | -dashCircleRadius, -dashCircleRadius, dashCircleSize, dashCircleSize); 167 | canvas.drawArc( 168 | rect, insideStartAngles[i] * pi / 180, 90 * pi / 180, false, paint); 169 | } 170 | canvas.restore(); 171 | } 172 | 173 | @override 174 | bool shouldRepaint(CustomPainter oldDelegate) => true; 175 | } 176 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_clip_rotate_pulse_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-05 8 | /// 9 | 10 | class BallClipRotatePulseIndicator extends StatefulWidget { 11 | BallClipRotatePulseIndicator({ 12 | this.startAngle: -5, 13 | this.minRadius: 10, 14 | this.maxRadius: 20, 15 | this.solidCircleRadius: 10, 16 | this.color: Colors.white, 17 | this.duration: const Duration(milliseconds: 400), 18 | }); 19 | 20 | final double startAngle; 21 | final double minRadius; 22 | final double maxRadius; 23 | final double solidCircleRadius; 24 | final Color color; 25 | final Duration duration; 26 | 27 | @override 28 | State createState() => _BallClipRotatePulseIndicatorState(); 29 | } 30 | 31 | class _BallClipRotatePulseIndicatorState 32 | extends State 33 | with SingleTickerProviderStateMixin { 34 | Animation _radius; 35 | Animation _rotate; 36 | AnimationController _controller; 37 | 38 | @override 39 | void initState() { 40 | _controller = AnimationController(duration: widget.duration, vsync: this); 41 | _radius = 42 | Tween(begin: widget.minRadius, end: widget.maxRadius).animate( 43 | CurvedAnimation( 44 | parent: _controller, 45 | curve: Interval(0, 1, curve: Curves.fastOutSlowIn), 46 | ), 47 | ); 48 | _rotate = Tween( 49 | begin: 0, 50 | end: 180, 51 | ).animate( 52 | CurvedAnimation( 53 | parent: _controller, 54 | curve: Interval(0, 1, curve: Curves.fastOutSlowIn), 55 | ), 56 | ); 57 | _controller.addStatusListener((AnimationStatus status) { 58 | if (status == AnimationStatus.completed) { 59 | _controller.reverse(); 60 | } else if (status == AnimationStatus.dismissed) { 61 | _controller.forward(); 62 | } 63 | }); 64 | _controller.forward(); 65 | super.initState(); 66 | } 67 | 68 | @override 69 | void dispose() { 70 | _controller?.dispose(); 71 | super.dispose(); 72 | } 73 | 74 | Size _measureSize() { 75 | return Size(widget.maxRadius * 2, widget.maxRadius * 2); 76 | } 77 | 78 | @override 79 | Widget build(BuildContext context) { 80 | return AnimatedBuilder( 81 | animation: _controller, 82 | builder: (context, child) { 83 | return CustomPaint( 84 | size: _measureSize(), 85 | painter: _BallClipRotatePulseIndicatorPainter( 86 | angle: _rotate.value, 87 | radius: _radius.value, 88 | minRadius: widget.minRadius, 89 | maxRadius: widget.maxRadius, 90 | solidCircleRadius: widget.solidCircleRadius, 91 | startAngle: widget.startAngle, 92 | color: widget.color, 93 | ), 94 | ); 95 | }, 96 | ); 97 | } 98 | } 99 | 100 | double _progress = .0; 101 | double _lastExtent = .0; 102 | 103 | class _BallClipRotatePulseIndicatorPainter extends CustomPainter { 104 | _BallClipRotatePulseIndicatorPainter({ 105 | this.angle, 106 | this.radius, 107 | this.minRadius, 108 | this.maxRadius, 109 | this.solidCircleRadius, 110 | this.startAngle, 111 | this.color, 112 | }) : startAngles = [225, 45]; 113 | 114 | final double angle; 115 | final double radius; 116 | final double minRadius; 117 | final double maxRadius; 118 | final double solidCircleRadius; 119 | final double startAngle; 120 | final List startAngles; 121 | final Color color; 122 | 123 | @override 124 | void paint(Canvas canvas, Size size) { 125 | var paint = Paint() 126 | ..isAntiAlias = true 127 | ..color = color 128 | ..strokeWidth = 2 129 | ..strokeCap = StrokeCap.round; 130 | 131 | _progress += (_lastExtent - angle).abs(); 132 | _lastExtent = angle; 133 | if (_progress >= double.maxFinite) { 134 | _progress = .0; 135 | _lastExtent = .0; 136 | } 137 | 138 | var halfWidth = size.width * .5; 139 | var halfHeight = size.height * .5; 140 | 141 | canvas.translate(halfWidth, halfHeight); 142 | canvas.rotate((_progress + startAngle) * pi / 180); 143 | var preScale = minRadius / maxRadius; 144 | var scale = preScale + (radius - minRadius) / maxRadius; 145 | canvas.scale(scale); 146 | 147 | paint.style = PaintingStyle.stroke; 148 | for (var i = 0; i < startAngles.length; i++) { 149 | Rect rect = 150 | Rect.fromLTWH(-halfWidth, -halfHeight, size.width, size.height); 151 | canvas.drawArc( 152 | rect, startAngles[i] * pi / 180, 90 * pi / 180, false, paint); 153 | } 154 | 155 | paint.style = PaintingStyle.fill; 156 | canvas.drawCircle(Offset(0, 0), solidCircleRadius, paint); 157 | } 158 | 159 | @override 160 | bool shouldRepaint(CustomPainter oldDelegate) => true; 161 | } 162 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_grid_beat_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author: Vans Z 8 | /// date: 2019-05-31 9 | /// 10 | 11 | class BallGridBeatIndicator extends StatefulWidget { 12 | BallGridBeatIndicator({ 13 | this.minAlpha: 51, 14 | this.maxAlpha: 255, 15 | this.radius: 7.2, 16 | this.spacing: 3, 17 | this.ballColor: Colors.white, 18 | this.duration: const Duration(milliseconds: 400), 19 | }); 20 | 21 | final int minAlpha; 22 | final int maxAlpha; 23 | final double radius; 24 | final double spacing; 25 | final Color ballColor; 26 | final Duration duration; 27 | 28 | @override 29 | State createState() => _BallGridBeatIndicatorState(); 30 | } 31 | 32 | class _BallGridBeatIndicatorState extends State 33 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 34 | @override 35 | void initState() { 36 | startEngine(this, widget.duration); 37 | super.initState(); 38 | } 39 | 40 | @override 41 | void dispose() { 42 | closeEngine(); 43 | super.dispose(); 44 | } 45 | 46 | @override 47 | Size measureSize() { 48 | var size = widget.radius * 2 * 3 + widget.spacing * 2; 49 | return Size(size, size); 50 | } 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return AnimatedBuilder( 55 | animation: controller, 56 | builder: (context, child) { 57 | return CustomPaint( 58 | size: measureSize(), 59 | painter: _BallGridBeatIndicatorPainter( 60 | animationValue: animationValue, 61 | radius: widget.radius, 62 | minAlpha: widget.minAlpha, 63 | maxAlpha: widget.maxAlpha, 64 | spacing: widget.spacing, 65 | ballColor: widget.ballColor, 66 | ), 67 | ); 68 | }, 69 | ); 70 | } 71 | } 72 | 73 | double _progress = .0; 74 | double _lastExtent = .0; 75 | 76 | class _BallGridBeatIndicatorPainter extends CustomPainter { 77 | _BallGridBeatIndicatorPainter({ 78 | this.animationValue, 79 | this.radius, 80 | this.minAlpha, 81 | this.maxAlpha, 82 | this.spacing, 83 | this.ballColor, 84 | }) : alphaList = [ 85 | minAlpha + (maxAlpha - minAlpha) * 0.9, 86 | minAlpha + (maxAlpha - minAlpha) * 0.8, 87 | minAlpha + (maxAlpha - minAlpha) * 0.7, 88 | minAlpha + (maxAlpha - minAlpha) * 0.6, 89 | minAlpha + (maxAlpha - minAlpha) * 0.5, 90 | minAlpha + (maxAlpha - minAlpha) * 0.4, 91 | minAlpha + (maxAlpha - minAlpha) * 0.3, 92 | minAlpha + (maxAlpha - minAlpha) * 0.2, 93 | minAlpha + (maxAlpha - minAlpha) * 0.1, 94 | ]; 95 | 96 | final double animationValue; 97 | final double radius; 98 | final int minAlpha; 99 | final int maxAlpha; 100 | final double spacing; 101 | final Color ballColor; 102 | final List alphaList; 103 | 104 | @override 105 | void paint(Canvas canvas, Size size) { 106 | var paint = Paint() 107 | ..isAntiAlias = true 108 | ..style = PaintingStyle.fill 109 | ..strokeJoin = StrokeJoin.round 110 | ..strokeCap = StrokeCap.round; 111 | 112 | _progress += (_lastExtent - animationValue).abs(); 113 | _lastExtent = animationValue; 114 | if (_progress >= double.maxFinite) { 115 | _progress = .0; 116 | _lastExtent = .0; 117 | } 118 | 119 | var diffAlpha = maxAlpha - minAlpha; 120 | for (int i = 0; i < alphaList.length; i++) { 121 | canvas.save(); 122 | int row = i ~/ 3; 123 | int column = i % 3; 124 | 125 | var dx = radius + 2 * column * radius + column * spacing; 126 | var dy = (2 * row + 1) * radius + row * spacing; 127 | var offset = Offset(dx, dy); 128 | 129 | var offsetAlpha = asin((alphaList[i] - minAlpha) / diffAlpha); 130 | var beatAlpha = 131 | sin(_progress * pi / 180 + offsetAlpha).abs() * diffAlpha + minAlpha; 132 | paint.color = Color.fromARGB( 133 | beatAlpha.round(), ballColor.red, ballColor.green, ballColor.blue); 134 | 135 | canvas.drawCircle(offset, radius, paint); 136 | canvas.restore(); 137 | } 138 | } 139 | 140 | @override 141 | bool shouldRepaint(CustomPainter oldDelegate) => true; 142 | } 143 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_grid_pulse_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author: Vans Z 8 | /// date: 2019-05-31 9 | /// 10 | 11 | class BallGridPulseIndicator extends StatefulWidget { 12 | BallGridPulseIndicator({ 13 | this.minRadius: 3.6, 14 | this.maxRadius: 7.2, 15 | this.minAlpha: 51, 16 | this.maxAlpha: 255, 17 | this.spacing: 3, 18 | this.ballColor: Colors.white, 19 | this.duration: const Duration(milliseconds: 400), 20 | }); 21 | 22 | final double minRadius; 23 | final double maxRadius; 24 | final double minAlpha; 25 | final double maxAlpha; 26 | final double spacing; 27 | final Color ballColor; 28 | final Duration duration; 29 | 30 | @override 31 | State createState() => _BallGridPulseIndicatorState(); 32 | } 33 | 34 | class _BallGridPulseIndicatorState extends State 35 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 36 | @override 37 | void initState() { 38 | startEngine(this, widget.duration); 39 | super.initState(); 40 | } 41 | 42 | @override 43 | void dispose() { 44 | closeEngine(); 45 | super.dispose(); 46 | } 47 | 48 | @override 49 | Size measureSize() { 50 | var size = widget.maxRadius * 2 * 3 + widget.spacing * 2; 51 | return Size(size, size); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return AnimatedBuilder( 57 | animation: controller, 58 | builder: (context, child) { 59 | return CustomPaint( 60 | size: measureSize(), 61 | painter: _BallGridPulseIndicatorPainter( 62 | animationValue: animationValue, 63 | minRadius: widget.minRadius, 64 | maxRadius: widget.maxRadius, 65 | minAlpha: widget.minAlpha, 66 | maxAlpha: widget.maxAlpha, 67 | spacing: widget.spacing, 68 | ballColor: widget.ballColor), 69 | ); 70 | }); 71 | } 72 | } 73 | 74 | double _progress = .0; 75 | double _lastExtent = .0; 76 | 77 | class _BallGridPulseIndicatorPainter extends CustomPainter { 78 | _BallGridPulseIndicatorPainter({ 79 | this.animationValue, 80 | this.minRadius, 81 | this.maxRadius, 82 | this.minAlpha, 83 | this.maxAlpha, 84 | this.spacing, 85 | this.ballColor, 86 | }) : radiusList = [ 87 | minRadius + (maxRadius - minRadius) * 0.9, 88 | minRadius + (maxRadius - minRadius) * 0.8, 89 | minRadius + (maxRadius - minRadius) * 0.7, 90 | minRadius + (maxRadius - minRadius) * 0.6, 91 | minRadius + (maxRadius - minRadius) * 0.5, 92 | minRadius + (maxRadius - minRadius) * 0.4, 93 | minRadius + (maxRadius - minRadius) * 0.3, 94 | minRadius + (maxRadius - minRadius) * 0.2, 95 | minRadius + (maxRadius - minRadius) * 0.1, 96 | ], 97 | alphaList = [ 98 | minAlpha + (maxAlpha - minAlpha) * 0.9, 99 | minAlpha + (maxAlpha - minAlpha) * 0.8, 100 | minAlpha + (maxAlpha - minAlpha) * 0.7, 101 | minAlpha + (maxAlpha - minAlpha) * 0.6, 102 | minAlpha + (maxAlpha - minAlpha) * 0.5, 103 | minAlpha + (maxAlpha - minAlpha) * 0.4, 104 | minAlpha + (maxAlpha - minAlpha) * 0.3, 105 | minAlpha + (maxAlpha - minAlpha) * 0.2, 106 | minAlpha + (maxAlpha - minAlpha) * 0.1, 107 | ]; 108 | final double animationValue; 109 | final double minRadius; 110 | final double maxRadius; 111 | final double minAlpha; 112 | final double maxAlpha; 113 | final double spacing; 114 | final Color ballColor; 115 | final List radiusList; 116 | final List alphaList; 117 | 118 | @override 119 | void paint(Canvas canvas, Size size) { 120 | var paint = Paint() 121 | ..isAntiAlias = true 122 | ..style = PaintingStyle.fill 123 | ..color = ballColor 124 | ..strokeJoin = StrokeJoin.round 125 | ..strokeCap = StrokeCap.round; 126 | 127 | _progress += (_lastExtent - animationValue).abs(); 128 | _lastExtent = animationValue; 129 | if (_progress >= double.maxFinite) { 130 | _progress = .0; 131 | _lastExtent = .0; 132 | } 133 | 134 | var diffRadius = maxRadius - minRadius; 135 | var diffAlpha = maxAlpha - minAlpha; 136 | for (int i = 0; i < radiusList.length; i++) { 137 | canvas.save(); 138 | int row = i ~/ 3; 139 | int column = i % 3; 140 | 141 | var dx = maxRadius + 2 * column * maxRadius + column * spacing; 142 | var dy = (2 * row + 1) * maxRadius + row * spacing; 143 | var offset = Offset(dx, dy); 144 | 145 | var offsetAlpha = asin((alphaList[i] - minAlpha) / diffAlpha); 146 | var beatAlpha = 147 | sin(_progress * pi / 180 + offsetAlpha).abs() * diffAlpha + minAlpha; 148 | paint.color = Color.fromARGB( 149 | beatAlpha.round(), ballColor.red, ballColor.green, ballColor.blue); 150 | 151 | var offsetExtent = asin((radiusList[i] - minRadius) / diffRadius); 152 | var scaleRadius = 153 | sin(_progress * pi / 180 + offsetExtent).abs() * diffRadius + 154 | minRadius; 155 | canvas.drawCircle(offset, scaleRadius, paint); 156 | canvas.restore(); 157 | } 158 | } 159 | 160 | @override 161 | bool shouldRepaint(CustomPainter oldDelegate) => true; 162 | } 163 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_pulse_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:math'; 3 | 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author:Vans Z 8 | /// date: 2019-05-27 9 | /// 10 | class BallPulseIndicator extends StatefulWidget { 11 | BallPulseIndicator({ 12 | this.minRadius: 2.4, 13 | this.maxRadius: 7.2, 14 | this.spacing: 3, 15 | this.ballColor: Colors.white, 16 | this.duration: const Duration(milliseconds: 400), 17 | }); 18 | 19 | final double minRadius; 20 | final double maxRadius; 21 | final double spacing; 22 | final Color ballColor; 23 | final Duration duration; 24 | 25 | @override 26 | State createState() => _BallPulseIndicatorState(); 27 | } 28 | 29 | class _BallPulseIndicatorState extends State 30 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 31 | @override 32 | void initState() { 33 | startEngine(this, widget.duration); 34 | super.initState(); 35 | } 36 | 37 | @override 38 | void dispose() { 39 | closeEngine(); 40 | super.dispose(); 41 | } 42 | 43 | @override 44 | Size measureSize() { 45 | var width = widget.maxRadius * 2 * 3 + widget.spacing * 2; 46 | var height = widget.maxRadius * 2; 47 | return Size(width, height); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return AnimatedBuilder( 53 | animation: controller, 54 | builder: (context, child) { 55 | return CustomPaint( 56 | size: measureSize(), 57 | painter: _BallPulseIndicatorPainter( 58 | animationValue: animationValue, 59 | minRadius: widget.minRadius, 60 | maxRadius: widget.maxRadius, 61 | spacing: widget.spacing, 62 | ballColor: widget.ballColor, 63 | ), 64 | ); 65 | }, 66 | ); 67 | } 68 | } 69 | 70 | double _progress = .0; 71 | double _lastExtent = .0; 72 | 73 | class _BallPulseIndicatorPainter extends CustomPainter { 74 | _BallPulseIndicatorPainter({ 75 | this.animationValue, 76 | this.minRadius, 77 | this.maxRadius, 78 | this.spacing, 79 | this.ballColor, 80 | }) : radiusList = [ 81 | minRadius + (maxRadius - minRadius) * 0.9, 82 | minRadius + (maxRadius - minRadius) * 0.6, 83 | minRadius + (maxRadius - minRadius) * 0.3, 84 | ]; 85 | 86 | final double animationValue; 87 | final double minRadius; 88 | final double maxRadius; 89 | final double spacing; 90 | final Color ballColor; 91 | final List radiusList; 92 | 93 | @override 94 | void paint(Canvas canvas, Size size) { 95 | var paint = Paint() 96 | ..isAntiAlias = true 97 | ..style = PaintingStyle.fill 98 | ..color = ballColor 99 | ..strokeJoin = StrokeJoin.round 100 | ..strokeCap = StrokeCap.round; 101 | 102 | _progress += (_lastExtent - animationValue).abs(); 103 | _lastExtent = animationValue; 104 | if (_progress >= double.maxFinite) { 105 | _progress = .0; 106 | _lastExtent = .0; 107 | } 108 | 109 | var diffRadius = maxRadius - minRadius; 110 | for (int i = 0; i < radiusList.length; i++) { 111 | var dx = maxRadius + 2 * i * maxRadius + i * spacing; 112 | var offset = Offset(dx, maxRadius); 113 | 114 | var offsetExtent = asin((radiusList[i] - minRadius) / diffRadius); 115 | var scaleRadius = 116 | sin(_progress * pi / 180 + offsetExtent).abs() * diffRadius + 117 | minRadius; 118 | canvas.drawCircle(offset, scaleRadius, paint); 119 | } 120 | } 121 | 122 | @override 123 | bool shouldRepaint(CustomPainter oldDelegate) => true; 124 | } 125 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_pulse_rise_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-07 8 | /// 9 | 10 | class BallPulseRiseIndicator extends StatefulWidget { 11 | BallPulseRiseIndicator({ 12 | this.ballRadius: 4.8, 13 | this.horizontalSpacing: 12, 14 | this.verticalSpacing: 24, 15 | this.color: Colors.white, 16 | this.duration: const Duration(milliseconds: 1250), 17 | }); 18 | 19 | final double ballRadius; 20 | final double horizontalSpacing; 21 | final double verticalSpacing; 22 | final Color color; 23 | final Duration duration; 24 | 25 | @override 26 | State createState() => _BallPulseRiseIndicatorState(); 27 | } 28 | 29 | class _BallPulseRiseIndicatorState extends State 30 | with SingleTickerProviderStateMixin { 31 | AnimationController _controller; 32 | Animation _rotateX; 33 | 34 | @override 35 | void initState() { 36 | _controller = AnimationController(vsync: this, duration: widget.duration); 37 | _rotateX = Tween(begin: 0, end: 360) 38 | .animate(CurvedAnimation(parent: _controller, curve: Curves.linear)); 39 | _controller.addListener(() { 40 | if (_controller.isCompleted) { 41 | _controller.reset(); 42 | _controller.forward(); 43 | } 44 | }); 45 | _controller.forward(); 46 | super.initState(); 47 | } 48 | 49 | @override 50 | void dispose() { 51 | _controller?.dispose(); 52 | super.dispose(); 53 | } 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | return AnimatedBuilder( 58 | animation: _controller, 59 | builder: (context, child) { 60 | return CustomPaint( 61 | size: _measureSize(), 62 | painter: _BallPulseRiseIndicatorPainter( 63 | rotateX: _rotateX.value, 64 | ballRadius: widget.ballRadius, 65 | horizontalSpacing: widget.horizontalSpacing, 66 | verticalSpacing: widget.verticalSpacing, 67 | color: widget.color, 68 | ), 69 | ); 70 | }, 71 | ); 72 | } 73 | 74 | Size _measureSize() { 75 | var width = widget.ballRadius * 2 * 3 + widget.horizontalSpacing * 2; 76 | var height = widget.ballRadius * 2 * 2 + widget.verticalSpacing; 77 | return Size(width, height); 78 | } 79 | } 80 | 81 | class _BallPulseRiseIndicatorPainter extends CustomPainter { 82 | _BallPulseRiseIndicatorPainter({ 83 | this.rotateX, 84 | this.ballRadius, 85 | this.horizontalSpacing, 86 | this.verticalSpacing, 87 | this.color, 88 | }); 89 | 90 | final double rotateX; 91 | final double ballRadius; 92 | final double horizontalSpacing; 93 | final double verticalSpacing; 94 | final Color color; 95 | 96 | @override 97 | void paint(Canvas canvas, Size size) { 98 | var paint = Paint() 99 | ..isAntiAlias = true 100 | ..style = PaintingStyle.fill 101 | ..color = color; 102 | 103 | var matrix = Matrix4.rotationX(rotateX * pi / 180); 104 | canvas.translate(0, size.height * .5); 105 | canvas.transform(matrix.storage); 106 | 107 | var dx, dy; 108 | 109 | dx = (size.width - 2 * ballRadius - horizontalSpacing) * .5; 110 | dy = (-verticalSpacing - ballRadius) * .5; 111 | canvas.drawCircle(Offset(dx, dy), ballRadius, paint); 112 | 113 | dx = size.width - dx; 114 | canvas.drawCircle(Offset(dx, dy), ballRadius, paint); 115 | 116 | dx = ballRadius; 117 | dy = verticalSpacing * .5 + ballRadius; 118 | canvas.drawCircle(Offset(dx, dy), ballRadius, paint); 119 | 120 | dx = 3 * ballRadius + horizontalSpacing; 121 | canvas.drawCircle(Offset(dx, dy), ballRadius, paint); 122 | 123 | dx = 5 * ballRadius + 2 * horizontalSpacing; 124 | canvas.drawCircle(Offset(dx, dy), ballRadius, paint); 125 | } 126 | 127 | @override 128 | bool shouldRepaint(CustomPainter oldDelegate) => true; 129 | } 130 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_pulse_sync_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author:Vans Z 8 | /// date: 2019-05-29 9 | /// 10 | 11 | class BallPulseSyncIndicator extends StatefulWidget { 12 | BallPulseSyncIndicator({ 13 | this.radius: 7.2, 14 | this.extent: 16, 15 | this.spacing: 3, 16 | this.ballColor: Colors.white, 17 | this.duration: const Duration(milliseconds: 400), 18 | }); 19 | 20 | final double radius; 21 | final double extent; 22 | final double spacing; 23 | final Color ballColor; 24 | final Duration duration; 25 | 26 | @override 27 | State createState() => _BallPulseSyncIndicatorState(); 28 | } 29 | 30 | class _BallPulseSyncIndicatorState extends State 31 | with TickerProviderStateMixin, InfiniteProgressMixin { 32 | 33 | @override 34 | void initState() { 35 | startEngine(this, widget.duration); 36 | super.initState(); 37 | } 38 | 39 | @override 40 | void dispose() { 41 | closeEngine(); 42 | super.dispose(); 43 | } 44 | 45 | @override 46 | Size measureSize() { 47 | var width = widget.radius * 2 * 3 + widget.spacing * 2; 48 | var height = widget.extent + widget.radius * 2; 49 | return Size(width, height); 50 | } 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return AnimatedBuilder( 55 | animation: controller, 56 | builder: (context, child){ 57 | return CustomPaint( 58 | size: measureSize(), 59 | painter: _BallPulseSyncIndicatorPainter( 60 | animationValue: animationValue, 61 | extent: widget.extent, 62 | radius: widget.radius, 63 | spacing: widget.spacing, 64 | ballColor: widget.ballColor, 65 | ), 66 | ); 67 | } 68 | ); 69 | } 70 | } 71 | 72 | double _progress = .0; 73 | double _lastExtent = .0; 74 | 75 | class _BallPulseSyncIndicatorPainter extends CustomPainter { 76 | _BallPulseSyncIndicatorPainter({ 77 | this.animationValue, 78 | this.extent, 79 | this.radius, 80 | this.spacing, 81 | this.ballColor, 82 | }) : extentList = [extent * 0.9, extent * 0.6, extent * 0.3]; 83 | 84 | final double animationValue; 85 | final double extent; 86 | final double radius; 87 | final double spacing; 88 | final Color ballColor; 89 | final List extentList; 90 | 91 | @override 92 | void paint(Canvas canvas, Size size) { 93 | var paint = Paint() 94 | ..isAntiAlias = true 95 | ..style = PaintingStyle.fill 96 | ..color = ballColor 97 | ..strokeJoin = StrokeJoin.round 98 | ..strokeCap = StrokeCap.round; 99 | 100 | _progress += (_lastExtent - animationValue).abs(); 101 | _lastExtent = animationValue; 102 | if (_progress >= double.maxFinite) { 103 | _progress = .0; 104 | _lastExtent = .0; 105 | } 106 | for (int i = 0; i < extentList.length; i++) { 107 | var dx = radius + 2 * i * radius + i * spacing; 108 | var offsetExtent = asin(extentList[i] / extent); 109 | var offsetY = sin(_progress * pi / 180 + offsetExtent).abs() * extent + radius; 110 | var offset = Offset(dx, offsetY); 111 | canvas.drawCircle(offset, radius, paint); 112 | } 113 | } 114 | 115 | @override 116 | bool shouldRepaint(CustomPainter oldDelegate) => true; 117 | } 118 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_rotate_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-07 8 | /// 9 | 10 | class BallRotateIndicator extends StatefulWidget { 11 | BallRotateIndicator({ 12 | this.minBallRadius: 2, 13 | this.maxBallRadius: 4, 14 | this.spacing: 7, 15 | this.color: Colors.white, 16 | this.duration: const Duration(milliseconds: 500), 17 | }); 18 | 19 | final double minBallRadius; 20 | final double maxBallRadius; 21 | final double spacing; 22 | final Color color; 23 | final Duration duration; 24 | 25 | @override 26 | State createState() => _BallRotateIndicatorState(); 27 | } 28 | 29 | class _BallRotateIndicatorState extends State 30 | with SingleTickerProviderStateMixin { 31 | AnimationController _controller; 32 | Animation _radius; 33 | Animation _rotate; 34 | 35 | @override 36 | void initState() { 37 | _controller = AnimationController(duration: widget.duration, vsync: this); 38 | _radius = Tween(begin: widget.minBallRadius, end: widget.maxBallRadius).animate( 39 | CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn), 40 | ); 41 | _rotate = Tween(begin: 0, end: 180).animate( 42 | CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn), 43 | ); 44 | _controller.addStatusListener((AnimationStatus status) { 45 | if (status == AnimationStatus.completed) { 46 | _controller.reverse(); 47 | } else if (status == AnimationStatus.dismissed) { 48 | _controller.forward(); 49 | } 50 | }); 51 | _controller.forward(); 52 | super.initState(); 53 | } 54 | 55 | @override 56 | void dispose() { 57 | _controller?.dispose(); 58 | super.dispose(); 59 | } 60 | 61 | Size measureSize() { 62 | var width = widget.maxBallRadius * 2 * 3 + widget.spacing * 2; 63 | var height = widget.maxBallRadius * 2; 64 | return Size(width, height); 65 | } 66 | 67 | @override 68 | Widget build(BuildContext context) => AnimatedBuilder( 69 | animation: _controller, 70 | builder: (context, child) => CustomPaint( 71 | size: measureSize(), 72 | painter: _BallRotateIndicatorPainter( 73 | angle: _rotate.value, 74 | radius: _radius.value, 75 | maxBallRadius: widget.maxBallRadius, 76 | minBallRadius: widget.minBallRadius, 77 | spacing: widget.spacing, 78 | color: widget.color, 79 | ), 80 | ), 81 | ); 82 | } 83 | 84 | double _progress = .0; 85 | double _lastExtent = .0; 86 | 87 | class _BallRotateIndicatorPainter extends CustomPainter { 88 | _BallRotateIndicatorPainter({ 89 | this.angle, 90 | this.radius, 91 | this.minBallRadius, 92 | this.maxBallRadius, 93 | this.spacing, 94 | this.color, 95 | }); 96 | 97 | final double angle; 98 | final double radius; 99 | final double minBallRadius; 100 | final double maxBallRadius; 101 | final double spacing; 102 | final Color color; 103 | 104 | @override 105 | void paint(Canvas canvas, Size size) { 106 | var paint = Paint() 107 | ..isAntiAlias = true 108 | ..style = PaintingStyle.fill 109 | ..color = color; 110 | 111 | _progress += (_lastExtent - angle).abs(); 112 | _lastExtent = angle; 113 | if (_progress >= double.maxFinite) { 114 | _progress = .0; 115 | _lastExtent = .0; 116 | } 117 | 118 | canvas.translate(size.width * .5, size.height * .5); 119 | canvas.rotate((_progress) * pi / 180); 120 | 121 | var preScale = minBallRadius / maxBallRadius; 122 | var scale = preScale + (radius - minBallRadius) / maxBallRadius; 123 | canvas.scale(scale); 124 | 125 | for (var i = 0; i < 3; i++) { 126 | var dx = (2 * i - 2) * maxBallRadius + (i - 1) * spacing; 127 | canvas.drawCircle(Offset(dx, 0), maxBallRadius, paint); 128 | } 129 | } 130 | 131 | @override 132 | bool shouldRepaint(CustomPainter oldDelegate) => true; 133 | } 134 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_scale_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 4 | /// author: Vans Z 5 | /// date: 2019-06-01 6 | /// 7 | 8 | class BallScaleIndicator extends StatefulWidget { 9 | BallScaleIndicator({ 10 | this.radius: 20, 11 | this.ballColor: Colors.white, 12 | this.duration: const Duration(milliseconds: 1000), 13 | }); 14 | 15 | final double radius; 16 | final Color ballColor; 17 | final Duration duration; 18 | 19 | @override 20 | State createState() => _BallScaleIndicatorState(); 21 | } 22 | 23 | class _BallScaleIndicatorState extends State 24 | with SingleTickerProviderStateMixin { 25 | Animation _animation; 26 | AnimationController _controller; 27 | 28 | @override 29 | void initState() { 30 | _controller = AnimationController(vsync: this, duration: widget.duration); 31 | _animation = CurvedAnimation(parent: _controller, curve: Curves.linear); 32 | _animation = Tween(begin: 0, end: widget.radius).animate(_animation) 33 | ..addStatusListener((AnimationStatus status) { 34 | if (status == AnimationStatus.completed) { 35 | _controller.reset(); 36 | _controller.forward(); 37 | } 38 | }); 39 | _controller.forward(); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | void dispose() { 45 | _controller?.dispose(); 46 | super.dispose(); 47 | } 48 | 49 | Size _measureSize() { 50 | var size = 2 * widget.radius; 51 | return Size(size, size); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return AnimatedBuilder( 57 | animation: _animation, 58 | builder: (context, child) { 59 | return CustomPaint( 60 | size: _measureSize(), 61 | painter: _BallScaleIndicatorPainter( 62 | animationValue: _animation.value, 63 | radius: widget.radius, 64 | ballColor: widget.ballColor, 65 | ), 66 | ); 67 | }, 68 | ); 69 | } 70 | } 71 | 72 | class _BallScaleIndicatorPainter extends CustomPainter { 73 | _BallScaleIndicatorPainter({ 74 | this.animationValue, 75 | this.radius, 76 | this.ballColor, 77 | }); 78 | 79 | final double animationValue; 80 | final double radius; 81 | final Color ballColor; 82 | 83 | @override 84 | void paint(Canvas canvas, Size size) { 85 | var paint = Paint() 86 | ..isAntiAlias = true 87 | ..color = Color.fromARGB((255 * (1 - animationValue / radius)).toInt(), 88 | ballColor.red, ballColor.green, ballColor.blue) 89 | ..style = PaintingStyle.fill; 90 | 91 | var center = Offset(radius, radius); 92 | canvas.drawCircle(center, animationValue, paint); 93 | } 94 | 95 | @override 96 | bool shouldRepaint(CustomPainter oldDelegate) => true; 97 | } 98 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_scale_multiple_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 4 | /// author: Vans Z 5 | /// date: 2019-06-01 6 | /// 7 | 8 | class BallScaleMultipleIndicator extends StatefulWidget { 9 | BallScaleMultipleIndicator({ 10 | this.radius: 20, 11 | this.ballColor: Colors.white, 12 | this.duration: const Duration(milliseconds: 1000), 13 | }); 14 | 15 | final double radius; 16 | final Color ballColor; 17 | final Duration duration; 18 | 19 | @override 20 | State createState() => _BallScaleMultipleIndicatorState(); 21 | } 22 | 23 | class _BallScaleMultipleIndicatorState extends State 24 | with SingleTickerProviderStateMixin { 25 | Animation _animation; 26 | AnimationController _controller; 27 | 28 | @override 29 | void initState() { 30 | _controller = AnimationController(vsync: this, duration: widget.duration); 31 | _animation = CurvedAnimation(parent: _controller, curve: Curves.linear); 32 | _animation = Tween(begin: 0, end: widget.radius).animate(_animation) 33 | ..addStatusListener((AnimationStatus status) { 34 | if (status == AnimationStatus.completed) { 35 | _controller.reset(); 36 | _controller.forward(); 37 | } 38 | }); 39 | _controller.forward(); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | void dispose() { 45 | _controller?.dispose(); 46 | super.dispose(); 47 | } 48 | 49 | Size _measureSize() { 50 | var size = 2 * widget.radius; 51 | return Size(size, size); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return AnimatedBuilder( 57 | animation: _animation, 58 | builder: (context, child) { 59 | return CustomPaint( 60 | size: _measureSize(), 61 | painter: _BallScaleMultipleIndicatorPainter( 62 | animationValue: _animation.value, 63 | radius: widget.radius, 64 | ballColor: widget.ballColor, 65 | duration: widget.duration, 66 | ), 67 | ); 68 | }, 69 | ); 70 | } 71 | } 72 | 73 | class _BallScaleMultipleIndicatorPainter extends CustomPainter { 74 | _BallScaleMultipleIndicatorPainter({ 75 | this.animationValue, 76 | this.radius, 77 | this.ballColor, 78 | this.duration, 79 | }) : offsetList = [radius, radius * .7, radius * .4]; 80 | 81 | final double animationValue; 82 | final double radius; 83 | final Color ballColor; 84 | final Duration duration; 85 | final List offsetList; 86 | 87 | @override 88 | void paint(Canvas canvas, Size size) { 89 | var percent = animationValue / radius; 90 | var paint = Paint() 91 | ..isAntiAlias = true 92 | ..color = Color.fromARGB((255 * (1 - percent)).toInt(), ballColor.red, 93 | ballColor.green, ballColor.blue) 94 | ..style = PaintingStyle.fill; 95 | 96 | var center = Offset(radius, radius); 97 | 98 | for (var i = 0; i < offsetList.length; i++) { 99 | canvas.save(); 100 | canvas.drawCircle(center, offsetList[i] * percent, paint); 101 | canvas.restore(); 102 | } 103 | } 104 | 105 | @override 106 | bool shouldRepaint(CustomPainter oldDelegate) => true; 107 | } 108 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_scale_ripple_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 4 | /// author: Vans Z 5 | /// date: 2019-06-03 6 | /// 7 | 8 | class BallScaleRippleIndicator extends StatefulWidget { 9 | BallScaleRippleIndicator({ 10 | this.radius: 20, 11 | this.ballColor: Colors.white, 12 | this.duration: const Duration(milliseconds: 1000), 13 | }); 14 | 15 | final double radius; 16 | final Color ballColor; 17 | final Duration duration; 18 | 19 | @override 20 | State createState() => _BallScaleRippleIndicatorState(); 21 | } 22 | 23 | class _BallScaleRippleIndicatorState extends State 24 | with SingleTickerProviderStateMixin { 25 | Animation _radius; 26 | Animation _alpha; 27 | AnimationController _controller; 28 | 29 | @override 30 | void initState() { 31 | _controller = AnimationController(vsync: this, duration: widget.duration); 32 | _radius = Tween(begin: 0, end: widget.radius) 33 | .animate(CurvedAnimation(parent: _controller, curve: Interval(0, 0.6))); 34 | _alpha = Tween(begin: 255, end: 0) 35 | .animate(CurvedAnimation(parent: _controller, curve: Interval(0.6, 1))); 36 | _controller.addStatusListener((AnimationStatus status) { 37 | if (status == AnimationStatus.completed) { 38 | _controller.reset(); 39 | _controller.forward(); 40 | } 41 | }); 42 | _controller.forward(); 43 | super.initState(); 44 | } 45 | 46 | @override 47 | void dispose() { 48 | _controller?.dispose(); 49 | super.dispose(); 50 | } 51 | 52 | Size _measureSize() { 53 | var size = 2 * widget.radius; 54 | return Size(size, size); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | return AnimatedBuilder( 60 | animation: _controller, 61 | builder: (context, child) { 62 | return CustomPaint( 63 | size: _measureSize(), 64 | painter: _BallScaleRippleIndicatorPainter( 65 | radiusAnimValue: _radius.value, 66 | alphaAnimValue: _alpha.value, 67 | totalRadius: widget.radius, 68 | ballColor: widget.ballColor, 69 | ), 70 | ); 71 | }, 72 | ); 73 | } 74 | } 75 | 76 | class _BallScaleRippleIndicatorPainter extends CustomPainter { 77 | _BallScaleRippleIndicatorPainter({ 78 | this.radiusAnimValue, 79 | this.alphaAnimValue, 80 | this.totalRadius, 81 | this.ballColor, 82 | }); 83 | 84 | final double radiusAnimValue; 85 | final double alphaAnimValue; 86 | final double totalRadius; 87 | final Color ballColor; 88 | 89 | @override 90 | void paint(Canvas canvas, Size size) { 91 | var percent = radiusAnimValue / totalRadius; 92 | var paint = Paint() 93 | ..isAntiAlias = true 94 | ..style = PaintingStyle.stroke 95 | ..strokeWidth = 1.2 * percent; 96 | 97 | if (alphaAnimValue >= 255) { 98 | paint.color = Color.fromARGB((255 * percent).round(), ballColor.red, 99 | ballColor.green, ballColor.blue); 100 | } else { 101 | paint.color = Color.fromARGB(alphaAnimValue.round(), ballColor.red, 102 | ballColor.green, ballColor.blue); 103 | } 104 | 105 | var center = Offset(totalRadius, totalRadius); 106 | canvas.drawCircle(center, radiusAnimValue, paint); 107 | } 108 | 109 | @override 110 | bool shouldRepaint(CustomPainter oldDelegate) => true; 111 | } 112 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_scale_ripple_multiple_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 4 | /// author: Vans Z 5 | /// date: 2019-06-01 6 | /// 7 | 8 | class BallScaleRippleMultipleIndicator extends StatefulWidget { 9 | BallScaleRippleMultipleIndicator({ 10 | this.radius: 20, 11 | this.ballColor: Colors.white, 12 | this.duration: const Duration(milliseconds: 1000), 13 | }); 14 | 15 | final double radius; 16 | final Color ballColor; 17 | final Duration duration; 18 | 19 | @override 20 | State createState() => 21 | _BallScaleRippleMultipleIndicatorState(); 22 | } 23 | 24 | class _BallScaleRippleMultipleIndicatorState 25 | extends State 26 | with SingleTickerProviderStateMixin { 27 | Animation _animation; 28 | AnimationController _controller; 29 | 30 | @override 31 | void initState() { 32 | _controller = AnimationController(vsync: this, duration: widget.duration); 33 | _animation = CurvedAnimation(parent: _controller, curve: Curves.linear); 34 | _animation = Tween(begin: 0, end: widget.radius).animate(_animation) 35 | ..addStatusListener((AnimationStatus status) { 36 | if (status == AnimationStatus.completed) { 37 | _controller.reset(); 38 | _controller.forward(); 39 | } 40 | }); 41 | _controller.forward(); 42 | super.initState(); 43 | } 44 | 45 | @override 46 | void dispose() { 47 | _controller?.dispose(); 48 | super.dispose(); 49 | } 50 | 51 | Size _measureSize() { 52 | var size = 2 * widget.radius; 53 | return Size(size, size); 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | return AnimatedBuilder( 59 | animation: _animation, 60 | builder: (context, child) { 61 | return CustomPaint( 62 | size: _measureSize(), 63 | painter: _BallScaleRippleMultipleIndicatorPainter( 64 | animationValue: _animation.value, 65 | radius: widget.radius, 66 | ballColor: widget.ballColor, 67 | duration: widget.duration, 68 | ), 69 | ); 70 | }, 71 | ); 72 | } 73 | } 74 | 75 | class _BallScaleRippleMultipleIndicatorPainter extends CustomPainter { 76 | _BallScaleRippleMultipleIndicatorPainter({ 77 | this.animationValue, 78 | this.radius, 79 | this.ballColor, 80 | this.duration, 81 | }) : offsetList = [radius, radius * .7, radius * .4], 82 | strokeList = [1.2, .84, 0.48]; 83 | 84 | final double animationValue; 85 | final double radius; 86 | final Color ballColor; 87 | final Duration duration; 88 | final List offsetList; 89 | final List strokeList; 90 | 91 | @override 92 | void paint(Canvas canvas, Size size) { 93 | var percent = animationValue / radius; 94 | var paint = Paint() 95 | ..isAntiAlias = true 96 | ..color = Color.fromARGB((255 * percent).round(), ballColor.red, 97 | ballColor.green, ballColor.blue) 98 | ..style = PaintingStyle.stroke; 99 | 100 | var center = Offset(radius, radius); 101 | 102 | for (var i = 0; i < offsetList.length; i++) { 103 | canvas.save(); 104 | paint.strokeWidth = strokeList[i] * percent; 105 | canvas.drawCircle(center, offsetList[i] * percent, paint); 106 | canvas.restore(); 107 | } 108 | } 109 | 110 | @override 111 | bool shouldRepaint(CustomPainter oldDelegate) => true; 112 | } 113 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_spin_fade_loader_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import '../infinite_progress.dart'; 6 | 7 | /// 8 | /// author: Vans Z 9 | /// date: 2019-06-02 10 | /// 11 | 12 | class BallSpinFadeLoaderIndicator extends StatefulWidget { 13 | BallSpinFadeLoaderIndicator({ 14 | this.radius = 24, 15 | this.minBallRadius: 1.6, 16 | this.maxBallRadius: 5, 17 | this.minBallAlpha: 77, 18 | this.maxBallAlpha: 255, 19 | this.ballColor: Colors.white, 20 | this.duration: const Duration(milliseconds: 500), 21 | }); 22 | 23 | final double radius; 24 | final double minBallRadius; 25 | final double maxBallRadius; 26 | final double minBallAlpha; 27 | final double maxBallAlpha; 28 | final Color ballColor; 29 | final Duration duration; 30 | 31 | @override 32 | State createState() => _BallSpinFadeLoaderIndicatorState(); 33 | } 34 | 35 | class _BallSpinFadeLoaderIndicatorState 36 | extends State 37 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 38 | @override 39 | void initState() { 40 | startEngine(this, widget.duration); 41 | super.initState(); 42 | } 43 | 44 | @override 45 | void dispose() { 46 | closeEngine(); 47 | super.dispose(); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return AnimatedBuilder( 53 | animation: controller, 54 | builder: (context, child) { 55 | return CustomPaint( 56 | size: _measureSize(), 57 | painter: _BallSpinFadeLoaderIndicatorPainter( 58 | animationValue: animationValue, 59 | minRadius: widget.minBallRadius, 60 | maxRadius: widget.maxBallRadius, 61 | minAlpha: widget.minBallAlpha, 62 | maxAlpha: widget.maxBallAlpha, 63 | ballColor: widget.ballColor), 64 | ); 65 | }, 66 | ); 67 | } 68 | 69 | Size _measureSize() { 70 | return Size(2 * widget.radius, 2 * widget.radius); 71 | } 72 | 73 | @override 74 | Size measureSize() { 75 | return Size(2 * widget.radius, 2 * widget.radius); 76 | } 77 | } 78 | 79 | double _progress = .0; 80 | double _lastExtent = .0; 81 | 82 | class _BallSpinFadeLoaderIndicatorPainter extends CustomPainter { 83 | _BallSpinFadeLoaderIndicatorPainter({ 84 | this.animationValue, 85 | this.minRadius, 86 | this.maxRadius, 87 | this.minAlpha, 88 | this.maxAlpha, 89 | this.ballColor, 90 | }); 91 | 92 | final double animationValue; 93 | final double minRadius; 94 | final double maxRadius; 95 | final double minAlpha; 96 | final double maxAlpha; 97 | final Color ballColor; 98 | 99 | @override 100 | void paint(Canvas canvas, Size size) { 101 | var paint = Paint() 102 | ..isAntiAlias = true 103 | ..style = PaintingStyle.fill; 104 | 105 | _progress += (_lastExtent - animationValue).abs(); 106 | _lastExtent = animationValue; 107 | if (_progress >= double.maxFinite) { 108 | _progress = .0; 109 | _lastExtent = .0; 110 | } 111 | 112 | var diffAlpha = maxAlpha - minAlpha; 113 | var diffRadius = maxRadius - minRadius; 114 | for (int i = 0; i < 8; i++) { 115 | canvas.save(); 116 | 117 | var newProgress = _progress - i * 22.5; 118 | var beatAlpha = sin(newProgress * pi / 180).abs() * diffAlpha + minAlpha; 119 | paint.color = Color.fromARGB( 120 | beatAlpha.round(), ballColor.red, ballColor.green, ballColor.blue); 121 | var scaleRadius = 122 | sin(newProgress * pi / 180).abs() * diffRadius + minRadius; 123 | var point = _circleAt(size.width * .5, size.height * .5, 124 | size.width * .5 - maxRadius, i * pi / 4); 125 | canvas.drawCircle(point, scaleRadius, paint); 126 | 127 | canvas.restore(); 128 | } 129 | } 130 | 131 | Offset _circleAt(double width, double height, double radius, double angle) { 132 | var x = width + radius * (cos(angle)); 133 | var y = height + radius * (sin(angle)); 134 | return Offset(x, y); 135 | } 136 | 137 | @override 138 | bool shouldRepaint(CustomPainter oldDelegate) => true; 139 | } 140 | -------------------------------------------------------------------------------- /lib/src/indicators/ball_zig_zag_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-06 8 | /// 9 | 10 | class BallZigZagIndicator extends StatefulWidget { 11 | BallZigZagIndicator({ 12 | this.width: 40, 13 | this.height: 40, 14 | this.ballRadius: 4.8, 15 | this.color: Colors.white, 16 | this.duration: const Duration(milliseconds: 1000), 17 | }); 18 | 19 | final double width; 20 | final double height; 21 | final double ballRadius; 22 | final Color color; 23 | final Duration duration; 24 | 25 | @override 26 | State createState() => _BallZigZagIndicatorState(); 27 | } 28 | 29 | class _BallZigZagIndicatorState extends State 30 | with SingleTickerProviderStateMixin { 31 | AnimationController _controller; 32 | Animation _horizontal; 33 | Animation _rightWaistX; 34 | Animation _rightWaistY; 35 | Animation _leftWaistX; 36 | Animation _leftWaistY; 37 | 38 | @override 39 | void initState() { 40 | _controller = AnimationController(vsync: this, duration: widget.duration); 41 | 42 | var waistLength = sqrt(pow(widget.width * .5 - widget.ballRadius, 2) + 43 | pow(widget.height * .5 - widget.ballRadius, 2)); 44 | var horizontalLength = widget.width - 2 * widget.ballRadius; 45 | var triangleLength = horizontalLength + 2 * waistLength; 46 | var horEndInterval = horizontalLength / triangleLength; 47 | var rightEndInterval = waistLength / triangleLength + horEndInterval; 48 | var leftEndInterval = waistLength / triangleLength + rightEndInterval; 49 | 50 | var begin = widget.ballRadius; 51 | var end = widget.width - widget.ballRadius; 52 | 53 | _horizontal = Tween(begin: begin, end: end).animate(CurvedAnimation( 54 | parent: _controller, curve: Interval(0, horEndInterval))); 55 | 56 | begin = widget.width - widget.ballRadius; 57 | end = widget.width * .5; 58 | _rightWaistX = Tween(begin: begin, end: end).animate( 59 | CurvedAnimation( 60 | parent: _controller, 61 | curve: Interval(horEndInterval, rightEndInterval))); 62 | begin = widget.ballRadius; 63 | end = widget.height * .5; 64 | _rightWaistY = Tween(begin: begin, end: end).animate( 65 | CurvedAnimation( 66 | parent: _controller, 67 | curve: Interval(horEndInterval, rightEndInterval))); 68 | 69 | begin = widget.width * .5; 70 | end = widget.ballRadius; 71 | _leftWaistX = Tween(begin: begin, end: end).animate(CurvedAnimation( 72 | parent: _controller, 73 | curve: Interval(rightEndInterval, leftEndInterval))); 74 | begin = widget.height * .5; 75 | end = widget.ballRadius; 76 | _leftWaistY = Tween(begin: begin, end: end).animate(CurvedAnimation( 77 | parent: _controller, 78 | curve: Interval(rightEndInterval, leftEndInterval))); 79 | 80 | _controller.addListener(() { 81 | if (_controller.isCompleted) { 82 | _controller.reset(); 83 | _controller.forward(); 84 | } 85 | }); 86 | _controller.forward(); 87 | 88 | super.initState(); 89 | } 90 | 91 | @override 92 | void dispose() { 93 | _controller?.dispose(); 94 | super.dispose(); 95 | } 96 | 97 | @override 98 | Widget build(BuildContext context) { 99 | return AnimatedBuilder( 100 | animation: _controller, 101 | builder: (context, child) => CustomPaint( 102 | size: Size(widget.width, widget.height), 103 | painter: _BallZigZagIndicatorPainter( 104 | horizontal: _horizontal.value, 105 | rightWaistX: _rightWaistX.value, 106 | rightWaistY: _rightWaistY.value, 107 | leftWaistX: _leftWaistX.value, 108 | leftWaistY: _leftWaistY.value, 109 | ballRadius: widget.ballRadius, 110 | color: widget.color, 111 | ), 112 | ), 113 | ); 114 | } 115 | } 116 | 117 | class _BallZigZagIndicatorPainter extends CustomPainter { 118 | _BallZigZagIndicatorPainter({ 119 | this.horizontal, 120 | this.rightWaistX, 121 | this.rightWaistY, 122 | this.leftWaistX, 123 | this.leftWaistY, 124 | this.ballRadius, 125 | this.color, 126 | }); 127 | 128 | final double horizontal; 129 | final double rightWaistX; 130 | final double rightWaistY; 131 | final double leftWaistX; 132 | final double leftWaistY; 133 | final double ballRadius; 134 | final Color color; 135 | 136 | @override 137 | void paint(Canvas canvas, Size size) { 138 | var paint = Paint() 139 | ..isAntiAlias = true 140 | ..style = PaintingStyle.fill 141 | ..color = color; 142 | 143 | canvas.save(); 144 | if (horizontal < size.width - ballRadius) { 145 | canvas.drawCircle(Offset(horizontal, ballRadius), ballRadius, paint); 146 | } else if (rightWaistX > size.width * .5 && 147 | rightWaistY < size.height * .5) { 148 | canvas.drawCircle(Offset(rightWaistX, rightWaistY), ballRadius, paint); 149 | } else if (leftWaistX > ballRadius && leftWaistY > ballRadius) { 150 | canvas.drawCircle(Offset(leftWaistX, leftWaistY), ballRadius, paint); 151 | } 152 | canvas.restore(); 153 | 154 | canvas.save(); 155 | canvas.translate(0, size.height); 156 | canvas.transform(Matrix4.rotationX(pi).storage); 157 | canvas.translate(size.width, 0); 158 | canvas.transform(Matrix4.rotationY(pi).storage); 159 | if (horizontal < size.width - ballRadius) { 160 | canvas.drawCircle(Offset(horizontal, ballRadius), ballRadius, paint); 161 | } else if (rightWaistX > size.width * .5 && 162 | rightWaistY < size.height * .5) { 163 | canvas.drawCircle(Offset(rightWaistX, rightWaistY), ballRadius, paint); 164 | } else if (leftWaistX > ballRadius && leftWaistY > ballRadius) { 165 | canvas.drawCircle(Offset(leftWaistX, leftWaistY), ballRadius, paint); 166 | } 167 | canvas.restore(); 168 | } 169 | 170 | @override 171 | bool shouldRepaint(CustomPainter oldDelegate) => true; 172 | } 173 | -------------------------------------------------------------------------------- /lib/src/indicators/cube_transition_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-06 8 | /// 9 | 10 | class CubeTransitionIndicator extends StatefulWidget { 11 | CubeTransitionIndicator({ 12 | this.size: 36, 13 | this.minCubeSize: 4, 14 | this.maxCubeSize: 8, 15 | this.cubeColor: Colors.white, 16 | this.duration: const Duration(milliseconds: 1600), 17 | }); 18 | 19 | final double size; 20 | final double minCubeSize; 21 | final double maxCubeSize; 22 | final Color cubeColor; 23 | final Duration duration; 24 | 25 | @override 26 | State createState() => _CubeTransitionIndicatorState(); 27 | } 28 | 29 | class _CubeTransitionIndicatorState extends State 30 | with SingleTickerProviderStateMixin { 31 | AnimationController _controller; 32 | Animation transX; 33 | Animation transReverseX; 34 | Animation transY; 35 | Animation transReverseY; 36 | 37 | @override 38 | void initState() { 39 | _controller = AnimationController(vsync: this, duration: widget.duration); 40 | var end = widget.size - widget.maxCubeSize; 41 | transX = Tween(begin: 0, end: end).animate( 42 | CurvedAnimation(parent: _controller, curve: Interval(0, 0.25))); 43 | transY = Tween(begin: 0, end: end).animate( 44 | CurvedAnimation(parent: _controller, curve: Interval(0.25, 0.5))); 45 | transReverseX = Tween(begin: 0, end: end).animate( 46 | CurvedAnimation(parent: _controller, curve: Interval(0.5, 0.75))); 47 | transReverseY = Tween(begin: 0, end: end).animate( 48 | CurvedAnimation(parent: _controller, curve: Interval(0.75, 1))); 49 | 50 | _controller.addListener(() { 51 | if (_controller.isCompleted) { 52 | _controller.reset(); 53 | _controller.forward(); 54 | } 55 | }); 56 | 57 | _controller.forward(); 58 | super.initState(); 59 | } 60 | 61 | @override 62 | void dispose() { 63 | _controller?.dispose(); 64 | super.dispose(); 65 | } 66 | 67 | @override 68 | Widget build(BuildContext context) => AnimatedBuilder( 69 | animation: _controller, 70 | builder: (context, child) { 71 | return CustomPaint( 72 | size: Size(widget.size, widget.size), 73 | painter: _CubeTransitionIndicatorPainter( 74 | transX: transX.value, 75 | transReverseX: transReverseX.value, 76 | transY: transY.value, 77 | transReverseY: transReverseY.value, 78 | minCubeSize: widget.minCubeSize, 79 | maxCubeSize: widget.maxCubeSize, 80 | color: widget.cubeColor, 81 | ), 82 | ); 83 | }, 84 | ); 85 | } 86 | 87 | class _CubeTransitionIndicatorPainter extends CustomPainter { 88 | _CubeTransitionIndicatorPainter({ 89 | this.transX, 90 | this.transReverseX, 91 | this.transY, 92 | this.transReverseY, 93 | this.minCubeSize, 94 | this.maxCubeSize, 95 | this.color, 96 | }); 97 | 98 | final double transX; 99 | final double transReverseX; 100 | final double transY; 101 | final double transReverseY; 102 | final double minCubeSize; 103 | final double maxCubeSize; 104 | final Color color; 105 | 106 | @override 107 | void paint(Canvas canvas, Size size) { 108 | var paint = Paint() 109 | ..isAntiAlias = true 110 | ..style = PaintingStyle.fill 111 | ..color = color; 112 | 113 | var end = size.width - maxCubeSize; 114 | drawLTCube(end, canvas, paint); 115 | drawRBCube(end, canvas, paint); 116 | } 117 | 118 | void drawRBCube(double end, Canvas canvas, Paint paint) { 119 | var percent, scale, dx, dy; 120 | final radian = pi / 180; 121 | final left = -maxCubeSize * .5; 122 | final top = -maxCubeSize * .5; 123 | 124 | canvas.save(); 125 | 126 | if (transX < end) { 127 | percent = transX / end; 128 | scale = 1 - (1 - minCubeSize / maxCubeSize) * percent; 129 | dx = end + maxCubeSize * .5 - transX; 130 | dy = end + maxCubeSize * .5; 131 | } else if (transY < end) { 132 | percent = transY / end; 133 | scale = (1 - minCubeSize / maxCubeSize) * percent + 0.5; 134 | dx = maxCubeSize * .5; 135 | dy = end + maxCubeSize * .5 - transY; 136 | } else if (transReverseX < end) { 137 | percent = transReverseX / end; 138 | scale = 1 - (1 - minCubeSize / maxCubeSize) * percent; 139 | dx = transReverseX + maxCubeSize * .5; 140 | dy = maxCubeSize * .5; 141 | } else if (transReverseY < end) { 142 | percent = transReverseY / end; 143 | scale = (1 - minCubeSize / maxCubeSize) * percent + 0.5; 144 | dx = end + maxCubeSize * .5; 145 | dy = transReverseY + maxCubeSize * .5; 146 | } 147 | 148 | canvas.translate(dx, dy); 149 | canvas.rotate(-90 * percent * radian); 150 | canvas.scale(scale); 151 | canvas.drawRect(Rect.fromLTWH(left, top, maxCubeSize, maxCubeSize), paint); 152 | 153 | canvas.restore(); 154 | } 155 | 156 | void drawLTCube(double end, Canvas canvas, Paint paint) { 157 | var percent, scale, dx, dy; 158 | final radian = pi / 180; 159 | final left = -maxCubeSize * .5; 160 | final top = -maxCubeSize * .5; 161 | 162 | canvas.save(); 163 | 164 | if (transX < end) { 165 | percent = transX / end; 166 | scale = 1 - (1 - minCubeSize / maxCubeSize) * percent; 167 | dx = transX + maxCubeSize * .5; 168 | dy = maxCubeSize * .5; 169 | } else if (transY < end) { 170 | percent = transY / end; 171 | scale = (1 - minCubeSize / maxCubeSize) * percent + 0.5; 172 | dx = end + maxCubeSize * .5; 173 | dy = transY + maxCubeSize * .5; 174 | } else if (transReverseX < end) { 175 | percent = transReverseX / end; 176 | scale = 1 - (1 - minCubeSize / maxCubeSize) * percent; 177 | dx = end + maxCubeSize * .5 - transReverseX; 178 | dy = end + maxCubeSize * .5; 179 | } else if (transReverseY < end) { 180 | percent = transReverseY / end; 181 | scale = (1 - minCubeSize / maxCubeSize) * percent + 0.5; 182 | dx = maxCubeSize * .5; 183 | dy = end + maxCubeSize * .5 - transReverseY; 184 | } 185 | 186 | canvas.translate(dx, dy); 187 | canvas.rotate(-90 * percent * radian); 188 | canvas.scale(scale); 189 | canvas.drawRect(Rect.fromLTWH(left, top, maxCubeSize, maxCubeSize), paint); 190 | 191 | canvas.restore(); 192 | } 193 | 194 | @override 195 | bool shouldRepaint(CustomPainter oldDelegate) => true; 196 | } 197 | -------------------------------------------------------------------------------- /lib/src/indicators/line_scale_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author: Vans Z 8 | /// date: 2019-06-01 9 | /// 10 | 11 | class LineScaleIndicator extends StatefulWidget { 12 | LineScaleIndicator({ 13 | this.maxLength: 38, 14 | this.minLength: 12, 15 | this.spacing: 3.5, 16 | this.lineWidth: 4, 17 | this.lineNum: 5, 18 | this.lineColor: Colors.white, 19 | this.duration: const Duration(milliseconds: 400), 20 | }); 21 | 22 | final double maxLength; 23 | final double minLength; 24 | final double lineWidth; 25 | final double spacing; 26 | final int lineNum; 27 | final Color lineColor; 28 | final Duration duration; 29 | 30 | @override 31 | State createState() => _LineScaleIndicatorState(); 32 | } 33 | 34 | class _LineScaleIndicatorState extends State 35 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 36 | @override 37 | void initState() { 38 | startEngine(this, widget.duration); 39 | super.initState(); 40 | } 41 | 42 | @override 43 | void dispose() { 44 | closeEngine(); 45 | super.dispose(); 46 | } 47 | 48 | @override 49 | Widget build(BuildContext context) { 50 | return AnimatedBuilder( 51 | animation: controller, 52 | builder: (context, child) { 53 | return CustomPaint( 54 | size: measureSize(), 55 | painter: _LineScaleIndicatorPainter( 56 | animationValue: animationValue, 57 | minLength: widget.minLength, 58 | maxLength: widget.maxLength, 59 | spacing: widget.spacing, 60 | lineNum: widget.lineNum, 61 | lineWidth: widget.lineWidth, 62 | lineColor: widget.lineColor, 63 | ), 64 | ); 65 | }, 66 | ); 67 | } 68 | 69 | @override 70 | Size measureSize() { 71 | var width = widget.lineNum * widget.lineWidth + 72 | (widget.lineNum - 1) * widget.spacing; 73 | return Size(width, widget.maxLength); 74 | } 75 | } 76 | 77 | double _progress = .0; 78 | double _lastExtent = .0; 79 | 80 | class _LineScaleIndicatorPainter extends CustomPainter { 81 | _LineScaleIndicatorPainter({ 82 | this.animationValue, 83 | this.minLength, 84 | this.maxLength, 85 | this.lineWidth, 86 | this.spacing, 87 | this.lineNum, 88 | this.lineColor, 89 | }) { 90 | offsetLength = []; 91 | var diffLength = maxLength - minLength; 92 | for (int i = 0; i < lineNum; i++) { 93 | offsetLength.add(minLength + diffLength * 2 * i / 10.0); 94 | } 95 | } 96 | 97 | final double animationValue; 98 | final double minLength; 99 | final double maxLength; 100 | final double lineWidth; 101 | final double spacing; 102 | final int lineNum; 103 | final Color lineColor; 104 | 105 | List offsetLength; 106 | 107 | @override 108 | void paint(Canvas canvas, Size size) { 109 | var paint = Paint() 110 | ..isAntiAlias = true 111 | ..style = PaintingStyle.fill 112 | ..color = lineColor 113 | ..strokeJoin = StrokeJoin.round 114 | ..strokeCap = StrokeCap.round; 115 | 116 | _progress += (_lastExtent - animationValue).abs(); 117 | _lastExtent = animationValue; 118 | if (_progress >= double.maxFinite) { 119 | _progress = .0; 120 | _lastExtent = .0; 121 | } 122 | 123 | var diffLength = maxLength - minLength; 124 | for (int i = 0; i < lineNum; i++) { 125 | var offsetExtent = asin((offsetLength[i] - minLength) / diffLength); 126 | var scaleLength = 127 | sin(_progress * pi / 180 + offsetExtent).abs() * diffLength + 128 | minLength; 129 | var left = (lineWidth + spacing) * i; 130 | var top = (maxLength - scaleLength) * .5; 131 | Rect rect = Rect.fromLTWH(left, top, lineWidth, scaleLength); 132 | RRect rRect = RRect.fromRectAndRadius(rect, Radius.circular(4.0)); 133 | canvas.drawRRect(rRect, paint); 134 | } 135 | } 136 | 137 | @override 138 | bool shouldRepaint(CustomPainter oldDelegate) => true; 139 | } 140 | -------------------------------------------------------------------------------- /lib/src/indicators/line_scale_pulse_out_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author: Vans Z 8 | /// date: 2019-06-01 9 | /// 10 | 11 | class LineScalePulseOutIndicator extends StatefulWidget { 12 | LineScalePulseOutIndicator({ 13 | this.maxLength: 42, 14 | this.minLength: 14, 15 | this.spacing: 3.5, 16 | this.lineWidth: 4, 17 | this.lineNum: 5, 18 | this.lineColor: Colors.white, 19 | this.duration: const Duration(milliseconds: 350), 20 | }); 21 | 22 | final double maxLength; 23 | final double minLength; 24 | final double lineWidth; 25 | final double spacing; 26 | final int lineNum; 27 | final Color lineColor; 28 | final Duration duration; 29 | 30 | @override 31 | State createState() => 32 | _LineScalePulseOutIndicatorState(); 33 | } 34 | 35 | class _LineScalePulseOutIndicatorState 36 | extends State 37 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 38 | @override 39 | void initState() { 40 | startEngine(this, widget.duration); 41 | super.initState(); 42 | } 43 | 44 | @override 45 | void dispose() { 46 | closeEngine(); 47 | super.dispose(); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return AnimatedBuilder( 53 | animation: controller, 54 | builder: (context, child) { 55 | return CustomPaint( 56 | size: measureSize(), 57 | painter: _LineScalePulseOutIndicatorPainter( 58 | animationValue: animationValue, 59 | minLength: widget.minLength, 60 | maxLength: widget.maxLength, 61 | spacing: widget.spacing, 62 | lineNum: widget.lineNum, 63 | lineWidth: widget.lineWidth, 64 | lineColor: widget.lineColor, 65 | ), 66 | ); 67 | }, 68 | ); 69 | } 70 | 71 | @override 72 | Size measureSize() { 73 | var width = widget.lineNum * widget.lineWidth + 74 | (widget.lineNum - 1) * widget.spacing; 75 | return Size(width, widget.maxLength); 76 | } 77 | } 78 | 79 | double _progress = .0; 80 | double _lastExtent = .0; 81 | 82 | class _LineScalePulseOutIndicatorPainter extends CustomPainter { 83 | _LineScalePulseOutIndicatorPainter({ 84 | this.animationValue, 85 | this.minLength, 86 | this.maxLength, 87 | this.lineWidth, 88 | this.spacing, 89 | this.lineNum, 90 | this.lineColor, 91 | }) : offsetLength = [ 92 | minLength + (maxLength - minLength) * .2, 93 | minLength + (maxLength - minLength) * .8, 94 | minLength, 95 | minLength + (maxLength - minLength) * .8, 96 | minLength + (maxLength - minLength) * .2, 97 | ]; 98 | 99 | final double animationValue; 100 | final double minLength; 101 | final double maxLength; 102 | final double lineWidth; 103 | final double spacing; 104 | final int lineNum; 105 | final Color lineColor; 106 | final List offsetLength; 107 | 108 | @override 109 | void paint(Canvas canvas, Size size) { 110 | var paint = Paint() 111 | ..isAntiAlias = true 112 | ..style = PaintingStyle.fill 113 | ..color = lineColor 114 | ..strokeJoin = StrokeJoin.round 115 | ..strokeCap = StrokeCap.round; 116 | 117 | _progress += (_lastExtent - animationValue).abs(); 118 | _lastExtent = animationValue; 119 | if (_progress >= double.maxFinite) { 120 | _progress = .0; 121 | _lastExtent = .0; 122 | } 123 | 124 | var diffLength = maxLength - minLength; 125 | for (int i = 0; i < lineNum; i++) { 126 | var offsetExtent = asin((offsetLength[i] - minLength) / diffLength); 127 | var scaleLength = 128 | sin(_progress * pi / 180 + offsetExtent).abs() * diffLength + 129 | minLength; 130 | var left = (lineWidth + spacing) * i; 131 | var top = (maxLength - scaleLength) * .5; 132 | Rect rect = Rect.fromLTWH(left, top, lineWidth, scaleLength); 133 | RRect rRect = RRect.fromRectAndRadius(rect, Radius.circular(4.0)); 134 | canvas.drawRRect(rRect, paint); 135 | } 136 | } 137 | 138 | @override 139 | bool shouldRepaint(CustomPainter oldDelegate) => true; 140 | } 141 | -------------------------------------------------------------------------------- /lib/src/indicators/line_scale_pulse_out_rapid_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:loading_indicator_view/src/infinite_progress.dart'; 5 | 6 | /// 7 | /// author: Vans Z 8 | /// date: 2019-06-01 9 | /// 10 | 11 | class LineScalePulseOutRapidIndicator extends StatefulWidget { 12 | LineScalePulseOutRapidIndicator({ 13 | this.maxLength: 38, 14 | this.minLength: 12, 15 | this.spacing: 3.5, 16 | this.lineWidth: 4, 17 | this.lineNum: 5, 18 | this.lineColor: Colors.white, 19 | this.duration: const Duration(milliseconds: 400), 20 | }); 21 | 22 | final double maxLength; 23 | final double minLength; 24 | final double lineWidth; 25 | final double spacing; 26 | final int lineNum; 27 | final Color lineColor; 28 | final Duration duration; 29 | 30 | @override 31 | State createState() => 32 | _LineScalePulseOutRapidIndicatorState(); 33 | } 34 | 35 | class _LineScalePulseOutRapidIndicatorState 36 | extends State 37 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 38 | @override 39 | void initState() { 40 | startEngine(this, widget.duration); 41 | super.initState(); 42 | } 43 | 44 | @override 45 | void dispose() { 46 | closeEngine(); 47 | super.dispose(); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return AnimatedBuilder( 53 | animation: controller, 54 | builder: (context, child) { 55 | return CustomPaint( 56 | size: measureSize(), 57 | painter: _LineScalePulseOutRapidIndicatorPainter( 58 | animationValue: animationValue, 59 | minLength: widget.minLength, 60 | maxLength: widget.maxLength, 61 | spacing: widget.spacing, 62 | lineNum: widget.lineNum, 63 | lineWidth: widget.lineWidth, 64 | lineColor: widget.lineColor, 65 | ), 66 | ); 67 | }, 68 | ); 69 | } 70 | 71 | @override 72 | Size measureSize() { 73 | var width = widget.lineNum * widget.lineWidth + 74 | (widget.lineNum - 1) * widget.spacing; 75 | return Size(width, widget.maxLength); 76 | } 77 | } 78 | 79 | double _progress = .0; 80 | double _lastExtent = .0; 81 | 82 | class _LineScalePulseOutRapidIndicatorPainter extends CustomPainter { 83 | _LineScalePulseOutRapidIndicatorPainter({ 84 | this.animationValue, 85 | this.minLength, 86 | this.maxLength, 87 | this.lineWidth, 88 | this.spacing, 89 | this.lineNum, 90 | this.lineColor, 91 | }) : offsetLength = [ 92 | minLength + (maxLength - minLength) * .3, 93 | minLength + (maxLength - minLength) * .7, 94 | minLength, 95 | minLength + (maxLength - minLength) * .7, 96 | minLength + (maxLength - minLength) * .3, 97 | ]; 98 | 99 | final double animationValue; 100 | final double minLength; 101 | final double maxLength; 102 | final double lineWidth; 103 | final double spacing; 104 | final int lineNum; 105 | final Color lineColor; 106 | final List offsetLength; 107 | 108 | @override 109 | void paint(Canvas canvas, Size size) { 110 | var paint = Paint() 111 | ..isAntiAlias = true 112 | ..style = PaintingStyle.fill 113 | ..color = lineColor 114 | ..strokeJoin = StrokeJoin.round 115 | ..strokeCap = StrokeCap.round; 116 | 117 | _progress += (_lastExtent - animationValue).abs(); 118 | _lastExtent = animationValue; 119 | if (_progress >= double.maxFinite) { 120 | _progress = .0; 121 | _lastExtent = .0; 122 | } 123 | 124 | var diffLength = maxLength - minLength; 125 | for (int i = 0; i < lineNum; i++) { 126 | var offsetExtent = asin((offsetLength[i] - minLength) / diffLength); 127 | var scaleLength = 128 | sin(_progress * pi / 180 + offsetExtent).abs() * diffLength + 129 | minLength; 130 | var left = (lineWidth + spacing) * i; 131 | var top = (maxLength - scaleLength) * .5; 132 | Rect rect = Rect.fromLTWH(left, top, lineWidth, scaleLength); 133 | RRect rRect = RRect.fromRectAndRadius(rect, Radius.circular(4.0)); 134 | canvas.drawRRect(rRect, paint); 135 | } 136 | } 137 | 138 | @override 139 | bool shouldRepaint(CustomPainter oldDelegate) => true; 140 | } 141 | -------------------------------------------------------------------------------- /lib/src/indicators/line_spin_fade_loader_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import '../infinite_progress.dart'; 6 | 7 | /// 8 | /// author: Vans Z 9 | /// date: 2019-06-02 10 | /// 11 | 12 | class LineSpinFadeLoaderIndicator extends StatefulWidget { 13 | LineSpinFadeLoaderIndicator({ 14 | this.radius = 18, 15 | this.minLineWidth: 2.4, 16 | this.maxLineWidth: 4.8, 17 | this.minLineHeight: 4.8, 18 | this.maxLineHeight: 9.6, 19 | this.minBallAlpha: 77, 20 | this.maxBallAlpha: 255, 21 | this.ballColor: Colors.white, 22 | this.duration: const Duration(milliseconds: 500), 23 | }); 24 | 25 | final double radius; 26 | final double minLineWidth; 27 | final double maxLineWidth; 28 | final double minLineHeight; 29 | final double maxLineHeight; 30 | final double minBallAlpha; 31 | final double maxBallAlpha; 32 | final Color ballColor; 33 | final Duration duration; 34 | 35 | @override 36 | State createState() => _LineSpinFadeLoaderIndicatorState(); 37 | } 38 | 39 | class _LineSpinFadeLoaderIndicatorState 40 | extends State 41 | with SingleTickerProviderStateMixin, InfiniteProgressMixin { 42 | @override 43 | void initState() { 44 | startEngine(this, widget.duration); 45 | super.initState(); 46 | } 47 | 48 | @override 49 | void dispose() { 50 | closeEngine(); 51 | super.dispose(); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return AnimatedBuilder( 57 | animation: controller, 58 | builder: (context, child) { 59 | return CustomPaint( 60 | size: measureSize(), 61 | painter: _LineSpinFadeLoaderIndicatorPainter( 62 | animationValue: animationValue, 63 | minLineWidth: widget.minLineWidth, 64 | maxLineWidth: widget.maxLineWidth, 65 | minLineHeight: widget.minLineHeight, 66 | maxLineHeight: widget.maxLineHeight, 67 | minAlpha: widget.minBallAlpha, 68 | maxAlpha: widget.maxBallAlpha, 69 | ballColor: widget.ballColor), 70 | ); 71 | }, 72 | ); 73 | } 74 | 75 | @override 76 | Size measureSize() { 77 | return Size(2 * widget.radius, 2 * widget.radius); 78 | } 79 | } 80 | 81 | double _progress = .0; 82 | double _lastExtent = .0; 83 | 84 | class _LineSpinFadeLoaderIndicatorPainter extends CustomPainter { 85 | _LineSpinFadeLoaderIndicatorPainter({ 86 | this.animationValue, 87 | this.minLineWidth, 88 | this.maxLineWidth, 89 | this.minLineHeight, 90 | this.maxLineHeight, 91 | this.minAlpha, 92 | this.maxAlpha, 93 | this.ballColor, 94 | }); 95 | 96 | final double animationValue; 97 | final double minLineWidth; 98 | final double maxLineWidth; 99 | final double minLineHeight; 100 | final double maxLineHeight; 101 | final double minAlpha; 102 | final double maxAlpha; 103 | final Color ballColor; 104 | 105 | @override 106 | void paint(Canvas canvas, Size size) { 107 | var paint = Paint() 108 | ..isAntiAlias = true 109 | ..style = PaintingStyle.fill; 110 | 111 | _progress += (_lastExtent - animationValue).abs(); 112 | _lastExtent = animationValue; 113 | if (_progress >= double.maxFinite) { 114 | _progress = .0; 115 | _lastExtent = .0; 116 | } 117 | 118 | var diffAlpha = maxAlpha - minAlpha; 119 | var diffWidth = maxLineWidth - minLineWidth; 120 | var diffHeight = maxLineHeight - minLineHeight; 121 | for (int i = 0; i < 8; i++) { 122 | canvas.save(); 123 | 124 | var newProgress = _progress - i * 22.5; 125 | var beatAlpha = sin(newProgress * pi / 180).abs() * diffAlpha + minAlpha; 126 | paint.color = Color.fromARGB( 127 | beatAlpha.round(), ballColor.red, ballColor.green, ballColor.blue); 128 | var scaleWidth = 129 | sin(newProgress * pi / 180).abs() * diffWidth + minLineWidth; 130 | var scaleHeight = 131 | sin(newProgress * pi / 180).abs() * diffHeight + minLineHeight; 132 | var point = _circleAt(size.width * .5, size.height * .5, 133 | size.width * .5 - maxLineWidth, i * pi / 4); 134 | 135 | canvas.translate(point.dx, point.dy); 136 | canvas.rotate((90 + (i * 45)) * pi / 180); 137 | Rect rect = Rect.fromLTWH( 138 | -scaleWidth * .5, -scaleHeight * .5, scaleWidth, scaleHeight); 139 | RRect rRect = RRect.fromRectAndRadius(rect, Radius.circular(4.0)); 140 | canvas.drawRRect(rRect, paint); 141 | 142 | canvas.restore(); 143 | } 144 | } 145 | 146 | Offset _circleAt(double width, double height, double radius, double angle) { 147 | var x = width + radius * (cos(angle)); 148 | var y = height + radius * (sin(angle)); 149 | return Offset(x, y); 150 | } 151 | 152 | @override 153 | bool shouldRepaint(CustomPainter oldDelegate) => true; 154 | } 155 | -------------------------------------------------------------------------------- /lib/src/indicators/pacman_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-04 8 | /// 9 | 10 | class PacmanIndicator extends StatefulWidget { 11 | PacmanIndicator({ 12 | this.radius: 16, 13 | this.beanRadius: 4, 14 | this.color: Colors.white, 15 | this.duration: const Duration(milliseconds: 325), 16 | }); 17 | 18 | final double radius; 19 | final double beanRadius; 20 | final Color color; 21 | final Duration duration; 22 | 23 | @override 24 | State createState() => _PacmanIndicatorState(); 25 | } 26 | 27 | class _PacmanIndicatorState extends State 28 | with SingleTickerProviderStateMixin { 29 | AnimationController _controller; 30 | Animation pacman; 31 | Animation bean; 32 | 33 | @override 34 | void initState() { 35 | _controller = AnimationController(vsync: this, duration: widget.duration); 36 | pacman = Tween(begin: 0, end: 90) 37 | .animate(CurvedAnimation(parent: _controller, curve: Curves.linear)); 38 | bean = Tween(begin: 0, end: widget.radius * .5) 39 | .animate(CurvedAnimation(parent: _controller, curve: Curves.linear)); 40 | _controller.addStatusListener((AnimationStatus status) { 41 | if (status == AnimationStatus.completed) { 42 | _controller.reverse(); 43 | } else if (status == AnimationStatus.dismissed) { 44 | _controller.forward(); 45 | } 46 | }); 47 | _controller.forward(); 48 | super.initState(); 49 | } 50 | 51 | @override 52 | void dispose() { 53 | _controller?.dispose(); 54 | super.dispose(); 55 | } 56 | 57 | Size _measureSize() { 58 | var width = (widget.radius + widget.beanRadius) * 2; 59 | var height = widget.radius * 2; 60 | return Size(width, height); 61 | } 62 | 63 | @override 64 | Widget build(BuildContext context) { 65 | return AnimatedBuilder( 66 | animation: _controller, 67 | builder: (context, child) => CustomPaint( 68 | size: _measureSize(), 69 | painter: _PacmanIndicatorPainter( 70 | pacmanAngle: pacman.value, 71 | beanTransX: bean.value, 72 | radius: widget.radius, 73 | beanRadius: widget.beanRadius, 74 | color: widget.color, 75 | ), 76 | )); 77 | } 78 | } 79 | 80 | double _progress = .0; 81 | double _lastExtent = .0; 82 | 83 | class _PacmanIndicatorPainter extends CustomPainter { 84 | _PacmanIndicatorPainter({ 85 | this.pacmanAngle, 86 | this.beanTransX, 87 | this.radius, 88 | this.beanRadius, 89 | this.color, 90 | }); 91 | 92 | final double pacmanAngle; 93 | final double beanTransX; 94 | final double radius; 95 | final double beanRadius; 96 | final Color color; 97 | 98 | @override 99 | void paint(Canvas canvas, Size size) { 100 | var paint = Paint() 101 | ..isAntiAlias = true 102 | ..style = PaintingStyle.fill 103 | ..color = color; 104 | 105 | var width = radius * 2; 106 | var height = radius * 2; 107 | var radian = pi / 180; 108 | Rect rect = Rect.fromLTWH(0, 0, width, height); 109 | canvas.drawArc(rect, (0 + pacmanAngle * .5) * radian, 110 | (360 - pacmanAngle) * radian, true, paint); 111 | 112 | _progress += (_lastExtent - beanTransX).abs(); 113 | _lastExtent = beanTransX; 114 | if (_progress >= radius) { 115 | _progress = .0; 116 | _lastExtent = .0; 117 | } 118 | 119 | var beanAlpha = 255 - (122.5 * _progress / radius); 120 | paint.color = 121 | Color.fromARGB(beanAlpha.round(), color.red, color.green, color.blue); 122 | 123 | var cx = width + beanRadius; 124 | var cy = size.height * .5; 125 | canvas.drawCircle(Offset(cx - _progress, cy), beanRadius, paint); 126 | } 127 | 128 | @override 129 | bool shouldRepaint(CustomPainter oldDelegate) => true; 130 | } 131 | -------------------------------------------------------------------------------- /lib/src/indicators/semi_circle_spin_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-04 8 | /// 9 | 10 | class SemiCircleSpinIndicator extends StatefulWidget { 11 | SemiCircleSpinIndicator({ 12 | this.radius: 24, 13 | this.color: Colors.white, 14 | this.duration: const Duration(milliseconds: 600), 15 | }); 16 | 17 | final double radius; 18 | final Color color; 19 | final Duration duration; 20 | 21 | @override 22 | State createState() => _SemiCircleSpinIndicatorState(); 23 | } 24 | 25 | class _SemiCircleSpinIndicatorState extends State 26 | with SingleTickerProviderStateMixin { 27 | AnimationController _controller; 28 | Animation _animation; 29 | 30 | @override 31 | void initState() { 32 | _controller = AnimationController(vsync: this, duration: widget.duration); 33 | _animation = 34 | CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn); 35 | _animation = Tween(begin: 0, end: 360).animate(_animation) 36 | ..addStatusListener((AnimationStatus status) { 37 | if (status == AnimationStatus.completed) { 38 | _controller.reset(); 39 | _controller.forward(); 40 | } 41 | }); 42 | _controller.forward(); 43 | super.initState(); 44 | } 45 | 46 | @override 47 | void dispose() { 48 | _controller?.dispose(); 49 | super.dispose(); 50 | } 51 | 52 | Size _measureSize() { 53 | return Size(2 * widget.radius, 2 * widget.radius); 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | return AnimatedBuilder( 59 | animation: _animation, 60 | builder: (context, child) { 61 | return CustomPaint( 62 | size: _measureSize(), 63 | painter: _SemiCircleSpinIndicatorPainter( 64 | animationValue: _animation.value, 65 | color: widget.color, 66 | ), 67 | ); 68 | }, 69 | ); 70 | } 71 | } 72 | 73 | class _SemiCircleSpinIndicatorPainter extends CustomPainter { 74 | _SemiCircleSpinIndicatorPainter({ 75 | this.animationValue, 76 | this.color, 77 | }); 78 | 79 | final double animationValue; 80 | final Color color; 81 | 82 | @override 83 | void paint(Canvas canvas, Size size) { 84 | var paint = Paint() 85 | ..isAntiAlias = true 86 | ..style = PaintingStyle.fill 87 | ..color = color; 88 | 89 | canvas.translate(size.width * .5, size.height * .5); 90 | canvas.rotate(animationValue * pi / 180); 91 | Rect rect = Rect.fromLTWH( 92 | -size.width * .5, -size.height * .5, size.width, size.height); 93 | canvas.drawArc(rect, -60 * pi / 180, 120 * pi / 180, false, paint); 94 | } 95 | 96 | @override 97 | bool shouldRepaint(CustomPainter oldDelegate) => true; 98 | } 99 | -------------------------------------------------------------------------------- /lib/src/indicators/square_spin_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | 6 | /// 7 | /// author: Vans Z 8 | /// date: 2019-06-02 9 | /// 10 | 11 | class SquareSpinIndicator extends StatefulWidget { 12 | SquareSpinIndicator({ 13 | this.length = 36, 14 | this.color = Colors.white, 15 | this.duration = const Duration(milliseconds: 1250), 16 | }); 17 | 18 | final double length; 19 | final Color color; 20 | final Duration duration; 21 | 22 | @override 23 | State createState() => _SquareSpinIndicatorState(); 24 | } 25 | 26 | class _SquareSpinIndicatorState extends State 27 | with SingleTickerProviderStateMixin { 28 | AnimationController _controller; 29 | Animation _rotateX, _rotateY; 30 | 31 | @override 32 | void initState() { 33 | _controller = AnimationController(vsync: this, duration: widget.duration); 34 | _rotateX = Tween(begin: 0, end: 180) 35 | .animate(CurvedAnimation(parent: _controller, curve: Interval(0, 0.5))); 36 | _rotateY = Tween(begin: 0, end: 180) 37 | .animate(CurvedAnimation(parent: _controller, curve: Interval(0.5, 1))); 38 | _controller.addListener(() { 39 | if (_controller.isCompleted) { 40 | _controller.reset(); 41 | _controller.forward(); 42 | } 43 | }); 44 | _controller.forward(); 45 | super.initState(); 46 | } 47 | 48 | @override 49 | void dispose() { 50 | _controller?.dispose(); 51 | super.dispose(); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return AnimatedBuilder( 57 | animation: _controller, 58 | builder: (context, child) { 59 | return CustomPaint( 60 | size: _measureSize(), 61 | painter: _SquareSpinIndicatorPainter( 62 | rotateX: _rotateX.value, 63 | rotateY: _rotateY.value, 64 | color: widget.color, 65 | ), 66 | ); 67 | }, 68 | ); 69 | } 70 | 71 | Size _measureSize() => Size(widget.length, widget.length); 72 | } 73 | 74 | class _SquareSpinIndicatorPainter extends CustomPainter { 75 | _SquareSpinIndicatorPainter({ 76 | this.rotateX, 77 | this.rotateY, 78 | this.color, 79 | }); 80 | 81 | final double rotateX; 82 | final double rotateY; 83 | final Color color; 84 | 85 | @override 86 | void paint(Canvas canvas, Size size) { 87 | var paint = Paint() 88 | ..isAntiAlias = true 89 | ..style = PaintingStyle.fill 90 | ..color = color; 91 | 92 | final halfLength = size.width * .5; 93 | var rect = Rect.fromLTWH(-halfLength, -halfLength, size.width, size.height); 94 | 95 | final radian = pi / 180; 96 | var matrix; 97 | if (rotateX < 180) { 98 | matrix = Matrix4.rotationX(rotateX * radian); 99 | } else if (rotateY < 180) { 100 | matrix = Matrix4.rotationY(rotateY * radian); 101 | } 102 | 103 | canvas.translate(halfLength, halfLength); 104 | canvas.transform(matrix.storage); 105 | canvas.drawRect(rect, paint); 106 | } 107 | 108 | @override 109 | bool shouldRepaint(CustomPainter oldDelegate) => true; 110 | } 111 | -------------------------------------------------------------------------------- /lib/src/indicators/triangle_skew_spin_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// author: Vans Z 7 | /// date: 2019-06-08 8 | /// 9 | 10 | class TriangleSkewSpinIndicator extends StatefulWidget { 11 | TriangleSkewSpinIndicator({ 12 | this.width: 42, 13 | this.height: 28, 14 | this.color: Colors.white, 15 | this.duration: const Duration(milliseconds: 1250), 16 | }); 17 | 18 | final double width; 19 | final double height; 20 | final Color color; 21 | final Duration duration; 22 | 23 | @override 24 | State createState() => _TriangleSkewSpinIndicatorState(); 25 | } 26 | 27 | class _TriangleSkewSpinIndicatorState extends State 28 | with SingleTickerProviderStateMixin { 29 | AnimationController _controller; 30 | Animation _rotateX, _rotateY; 31 | 32 | @override 33 | void initState() { 34 | _controller = AnimationController(vsync: this, duration: widget.duration); 35 | _rotateY = Tween(begin: 0, end: 180) 36 | .animate(CurvedAnimation(parent: _controller, curve: Interval(0, 0.5))); 37 | _rotateX = Tween(begin: 0, end: 180) 38 | .animate(CurvedAnimation(parent: _controller, curve: Interval(0.5, 1))); 39 | _controller.addListener(() { 40 | if (_controller.isCompleted) { 41 | _controller.reset(); 42 | _controller.forward(); 43 | _count++; 44 | } 45 | }); 46 | _controller.forward(); 47 | super.initState(); 48 | } 49 | 50 | @override 51 | void dispose() { 52 | _controller?.dispose(); 53 | super.dispose(); 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) => AnimatedBuilder( 58 | animation: _controller, 59 | builder: (context, child) => CustomPaint( 60 | size: Size(widget.width, widget.height), 61 | painter: _TriangleSkewSpinIndicatorPainter( 62 | rotateX: _rotateX.value, 63 | rotateY: _rotateY.value, 64 | color: widget.color, 65 | ), 66 | ), 67 | ); 68 | } 69 | 70 | var _count = 0; 71 | 72 | class _TriangleSkewSpinIndicatorPainter extends CustomPainter { 73 | _TriangleSkewSpinIndicatorPainter({ 74 | this.rotateX, 75 | this.rotateY, 76 | this.color, 77 | }); 78 | 79 | final double rotateX; 80 | final double rotateY; 81 | final Color color; 82 | 83 | @override 84 | void paint(Canvas canvas, Size size) { 85 | var paint = Paint() 86 | ..isAntiAlias = true 87 | ..style = PaintingStyle.fill 88 | ..color = color; 89 | 90 | final radian = pi / 180; 91 | var matrix; 92 | if (rotateY < 180) { 93 | matrix = Matrix4.rotationY(rotateY * radian); 94 | } else if (rotateX < 180) { 95 | matrix = Matrix4.rotationX(rotateX * radian); 96 | } 97 | 98 | final halfWidth = size.width * .5; 99 | final halfHeight = size.height * .5; 100 | 101 | var path; 102 | if (_count % 2 == 0) { 103 | path = Path() 104 | ..moveTo(0, halfHeight) 105 | ..lineTo(halfWidth, -halfHeight) 106 | ..lineTo(-halfWidth, -halfHeight) 107 | ..close(); 108 | } else { 109 | path = Path() 110 | ..moveTo(0, -halfHeight) 111 | ..lineTo(halfWidth, halfHeight) 112 | ..lineTo(-halfWidth, halfHeight) 113 | ..close(); 114 | } 115 | canvas.translate(halfWidth, halfHeight); 116 | canvas.transform(matrix.storage); 117 | canvas.drawPath(path, paint); 118 | } 119 | 120 | @override 121 | bool shouldRepaint(CustomPainter oldDelegate) => true; 122 | } 123 | -------------------------------------------------------------------------------- /lib/src/infinite_progress.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | /// 4 | /// author:Vans Z 5 | /// date: 2019-06-01 6 | /// 7 | 8 | mixin InfiniteProgressMixin { 9 | Animation _animation; 10 | AnimationController controller; 11 | 12 | double get animationValue => _animation.value; 13 | 14 | void startEngine(TickerProvider vsync, Duration duration) { 15 | controller = AnimationController(vsync: vsync, duration: duration); 16 | _animation = CurvedAnimation(parent: controller, curve: Curves.linear); 17 | _animation = Tween(begin: 0, end: 90).animate(_animation) 18 | ..addStatusListener((AnimationStatus status) { 19 | if (status == AnimationStatus.completed) { 20 | controller.reverse(); 21 | } else if (status == AnimationStatus.dismissed) { 22 | controller.forward(); 23 | } 24 | }); 25 | controller.forward(); 26 | } 27 | 28 | Size measureSize(); 29 | 30 | void closeEngine() { 31 | controller?.dispose(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /loading_indicator_view.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: loading_indicator_view 2 | description: Flutter loading indicator widget 3 | version: 1.1.0 4 | author: Vans Z <196425254@qq.com> 5 | homepage: https://github.com/Hitomis/loading_indicator_view 6 | 7 | environment: 8 | sdk: ">=2.1.0 <3.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | 18 | # For information on the generic Dart part of this file, see the 19 | # following page: https://dart.dev/tools/pub/pubspec 20 | 21 | # The following section is specific to Flutter. 22 | flutter: 23 | # This section identifies this Flutter project as a plugin project. 24 | # The androidPackage and pluginClass identifiers should not ordinarily 25 | # be modified. They are used by the tooling to maintain consistency when 26 | # adding or updating assets for this project. 27 | plugin: 28 | androidPackage: com.vansz.loading_indicator_view 29 | pluginClass: LoadingIndicatorViewPlugin 30 | 31 | # To add assets to your plugin package, add an assets section, like this: 32 | # assets: 33 | # - images/a_dot_burr.jpeg 34 | # - images/a_dot_ham.jpeg 35 | # 36 | # For details regarding assets in packages, see 37 | # https://flutter.dev/assets-and-images/#from-packages 38 | # 39 | # An image asset can refer to one or more resolution-specific "variants", see 40 | # https://flutter.dev/assets-and-images/#resolution-aware. 41 | 42 | # To add custom fonts to your plugin package, add a fonts section here, 43 | # in this "flutter" section. Each entry in this list should have a 44 | # "family" key with the font family name, and a "fonts" key with a 45 | # list giving the asset and other descriptors for the font. For 46 | # example: 47 | # fonts: 48 | # - family: Schyler 49 | # fonts: 50 | # - asset: fonts/Schyler-Regular.ttf 51 | # - asset: fonts/Schyler-Italic.ttf 52 | # style: italic 53 | # - family: Trajan Pro 54 | # fonts: 55 | # - asset: fonts/TrajanPro.ttf 56 | # - asset: fonts/TrajanPro_Bold.ttf 57 | # weight: 700 58 | # 59 | # For details regarding fonts in packages, see 60 | # https://flutter.dev/custom-fonts/#from-packages 61 | -------------------------------------------------------------------------------- /test/loading_indicator_view_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | const MethodChannel channel = MethodChannel('loading_indicator_view'); 6 | 7 | setUp(() { 8 | channel.setMockMethodCallHandler((MethodCall methodCall) async { 9 | return '42'; 10 | }); 11 | }); 12 | 13 | tearDown(() { 14 | channel.setMockMethodCallHandler(null); 15 | }); 16 | 17 | test('getPlatformVersion', () async { 18 | }); 19 | } 20 | --------------------------------------------------------------------------------