├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ └── bug_report.md
├── dependabot.yml
└── workflows
│ └── main.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example
├── .gitignore
├── .metadata
├── README.md
├── analysis_options.yaml
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable-v21
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── 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-night
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── example.iml
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── 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
│ │ └── Runner-Bridging-Header.h
├── lib
│ ├── main.dart
│ ├── showcase.dart
│ └── workspace.dart
├── macos
│ ├── .gitignore
│ ├── Flutter
│ │ ├── Flutter-Debug.xcconfig
│ │ ├── Flutter-Release.xcconfig
│ │ └── GeneratedPluginRegistrant.swift
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_512.png
│ │ │ └── app_icon_64.png
│ │ ├── Base.lproj
│ │ └── MainMenu.xib
│ │ ├── Configs
│ │ ├── AppInfo.xcconfig
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── Warnings.xcconfig
│ │ ├── DebugProfile.entitlements
│ │ ├── Info.plist
│ │ ├── MainFlutterWindow.swift
│ │ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
└── web
│ ├── favicon.png
│ ├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
│ ├── index.html
│ └── manifest.json
├── flutter_spinkit.iml
├── lib
├── flutter_spinkit.dart
└── src
│ ├── chasing_dots.dart
│ ├── circle.dart
│ ├── cube_grid.dart
│ ├── dancing_square.dart
│ ├── double_bounce.dart
│ ├── dual_ring.dart
│ ├── fading_circle.dart
│ ├── fading_cube.dart
│ ├── fading_four.dart
│ ├── fading_grid.dart
│ ├── folding_cube.dart
│ ├── hour_glass.dart
│ ├── piano_wave.dart
│ ├── pouring_hour_glass.dart
│ ├── pouring_hour_glass_refined.dart
│ ├── pulse.dart
│ ├── pulsing_grid.dart
│ ├── pumping_heart.dart
│ ├── ring.dart
│ ├── ripple.dart
│ ├── rotating_circle.dart
│ ├── rotating_plain.dart
│ ├── spinning_circle.dart
│ ├── spinning_lines.dart
│ ├── square_circle.dart
│ ├── three_bounce.dart
│ ├── three_in_out.dart
│ ├── tweens
│ └── delay_tween.dart
│ ├── wandering_cubes.dart
│ ├── wave.dart
│ └── wave_spinner.dart
├── makefile
├── pubspec.yaml
├── screenshots
├── FadingCube.gif
├── FadingFour.gif
├── PouringHourGlass.gif
├── dancing-square.gif
├── dual-ring.gif
├── grid.gif
├── heart.gif
├── hour-glass.gif
├── itemBuilder.gif
├── piano-wave.gif
├── pouring-hour-glass-refined.gif
├── pulsing-grid.gif
├── ring.gif
├── ripple.gif
├── spinkit_wave_spinner.gif
├── spinning-circle.gif
├── spinning-lines.gif
├── square_circle.gif
└── three-in-out.gif
└── test
├── chasing_dots_test.dart
├── circle_test.dart
├── cube_grid_test.dart
├── dancing_square_test.dart
├── double_bounce_test.dart
├── dual_ring_test.dart
├── fading_circle_test.dart
├── fading_cube_test.dart
├── fading_four_test.dart
├── fading_grid_test.dart
├── folding_cube_test.dart
├── helpers.dart
├── hour_glass_test.dart
├── piano_wave_test.dart
├── pouring_hour_glass_refined_test.dart
├── pouring_hour_glass_test.dart
├── pulse_test.dart
├── pulsing_grid_test.dart
├── pumping_heart_test.dart
├── ring_test.dart
├── ripple_test.dart
├── rotating_circle_test.dart
├── rotating_plain_test.dart
├── smoke_test.dart
├── spinning_circle_test.dart
├── spinning_line_test.dart
├── square_circle_test.dart
├── three_bounce_test.dart
├── three_in_out_test.dart
├── wandering_cubes_test.dart
├── wave_spinner_test.dart
└── wave_test.dart
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: ['www.paypal.me/jogboms']
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **SpinKit name**
11 | The name of the loader with which this bug occurred.
12 |
13 | **Screenshots**
14 | If applicable, add screenshots to help explain your problem.
15 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "github-actions"
9 | directory: "/"
10 | schedule:
11 | interval: "weekly"
12 | - package-ecosystem: "pub"
13 | directory: "/"
14 | schedule:
15 | interval: "weekly"
16 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Format, Analyze and Test
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 | schedule:
11 | # runs the CI weekly
12 | - cron: "0 0 * * 0"
13 |
14 | jobs:
15 | default_run:
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - uses: actions/checkout@v4
20 | - uses: actions/setup-java@v1
21 | with:
22 | java-version: "12.x"
23 | - uses: subosito/flutter-action@v2
24 | with:
25 | cache: true
26 | channel: 'stable'
27 | - run: flutter doctor
28 | - run: flutter pub get
29 | - run: dart format --set-exit-if-changed -l 120 lib -l 120 example
30 | - run: flutter analyze lib example
31 | - run: flutter test --no-pub --coverage
32 |
33 | - name: Upload coverage to codecov
34 | uses: codecov/codecov-action@v4
35 | with:
36 | token: ${{ secrets.CODECOV_TOKEN }}
37 | fail_ci_if_error: true
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | .vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
26 | /pubspec.lock
27 | **/doc/api/
28 | .dart_tool/
29 | .packages
30 | build/
31 |
32 | # Custom
33 | .pub/
34 | coverage/
35 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # ChangeLog for Flutter Spinkit
2 |
3 | A collection of loading indicators animated with flutter. Heavily inspired by @tobiasahlin's SpinKit.
4 |
5 | ## 5.2.1
6 |
7 | - Fix `SpinKitCubeGrid` not working as showcased
8 |
9 | ## 5.2.0
10 |
11 | - Fix `SpinKitCircle`, `SpinKitFadingCircle`, `SpinKitDancingSquare` animation
12 | - Fix calling `setState` on unmounted states
13 | - Introduced [SpinKitWaveSpinner]
14 | - Introduced [SpinKitPulsingGrid]
15 |
16 | ## 5.1.0
17 |
18 | - Renamed `SpinKitPouringHourglass` -> `SpinKitPouringHourGlass` for correctness
19 | - Fix `SpinKitFoldingCube` animation
20 | - Fix disposing of non-local animation controllers
21 | - Introduced `strokeWidth` to pouring glass animation
22 | - Introduced `SpinKitPouringHourGlassRefined`
23 | - Introduced `SpinKitSpinningLines`
24 | - Introduced `SpinKitPianoWave`
25 | - Introduced `SpinKitDancingSquare`
26 | - Introduced `SpinKitThreeInOut`
27 |
28 | ## 5.0.0
29 |
30 | - Migrate to null safety
31 |
32 | ## 4.1.2+1
33 |
34 | - Upgrades the example to AndroidX
35 |
36 | ## 4.1.2
37 |
38 | - Introduced new `itemCount` property to `SpinKitWave`
39 | - Fixed broken calculations that made certain animations behave weirdly
40 |
41 | ## 4.1.1+1
42 |
43 | - Include Authors info in README
44 |
45 | ## 4.1.1
46 |
47 | - Utilize native flutter auto-reverse feature for AnimationController
48 |
49 | ## 4.1.0
50 |
51 | - Introduces a new SpinKit [SpinKitSquareCircle]
52 | - Introduces `const` SpinKits
53 | - Improve code quality across all spinners
54 |
55 | ### Before
56 |
57 | ```dart
58 | final spinkit = SpinKitSquareCircle(color: Colors.white, size: 50.0);
59 | ```
60 |
61 | ### Now, all SpinKits can be initialized as `const`s
62 |
63 | ```dart
64 | const spinkit = SpinKitSquareCircle(color: Colors.white, size: 50.0);
65 | ```
66 |
67 |
68 |
69 | ## 4.0.0
70 |
71 | ### Feature
72 |
73 | - `controller` parameter [5873e7](https://github.com/jogboms/flutter_spinkit/commit/5873e75430aca52d2ec0c483dcd71a02438f3e8b). Closes [#51](https://github.com/jogboms/flutter_spinkit/issues/51)
74 |
75 | ```dart
76 | final spinkit = SpinKitFadingCircle(
77 | color: Colors.white,
78 | size: 50.0,
79 | controller: AnimationController(vsync: this, duration: const Duration(milliseconds: 1200)),
80 | );
81 | ```
82 | - [DualRing] `lineWidth` parameter [9bcfd5](https://github.com/jogboms/flutter_spinkit/commit/9bcfd507459dfabf50d26a27cdb2c11188fce913). Closes [#42](https://github.com/jogboms/flutter_spinkit/issues/42)
83 |
84 | ## 3.1.0
85 |
86 | ### Feature
87 |
88 | - `duration` parameter [70b113b](https://github.com/jogboms/flutter_spinkit/commit/70b113b384200e344336d521704a1c96d2864909)
89 |
90 | ### Fixes
91 |
92 | - state disposed before ticker [0c9b6e3](https://github.com/jogboms/flutter_spinkit/commit/0c9b6e388c2f714659b945ece7feb3b7480ba0de)
93 |
94 | ## 3.0.0
95 |
96 | ### Before
97 |
98 | ```dart
99 | final spinkit = SpinKitFadingCircle(color: Colors.white, size: 50.0);
100 | ```
101 |
102 | ### Now, there is an itemBuilder alternative
103 |
104 | ```dart
105 | final spinkit = SpinKitFadingCircle(
106 | itemBuilder: (_, int index) {
107 | return DecoratedBox(
108 | decoration: BoxDecoration(
109 | color: index.isEven ? Colors.red : Colors.green,
110 | ),
111 | );
112 | },
113 | );
114 | ```
115 |
116 | ### Which produces
117 |
118 |
119 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Jeremiah Ogbomo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | analyzer:
4 | errors:
5 | missing_required_param: error
6 | missing_return: error
7 | unused_import: error
8 | unused_local_variable: error
9 | dead_code: error
10 | todo: ignore
11 |
12 | linter:
13 | rules:
14 | # All rules from pedantic, already enabled rules are left out
15 | # https://github.com/google/pedantic/blob/master/lib/analysis_options.1.11.0.yaml
16 | - always_declare_return_types
17 | - prefer_single_quotes
18 | - unawaited_futures
19 |
20 | # Additional rules from https://github.com/flutter/flutter/blob/master/analysis_options.yaml
21 | # Not all rules are included
22 | - always_put_control_body_on_new_line
23 | - avoid_slow_async_io
24 | - cast_nullable_to_non_nullable
25 | - prefer_final_in_for_each
26 | - prefer_final_locals
27 | - prefer_foreach
28 | - prefer_if_elements_to_conditional_expressions
29 | - sort_constructors_first
30 | - sort_unnamed_constructors_first
31 | - test_types_in_equals
32 | - tighten_type_of_initializing_formals
33 | - unnecessary_await_in_return
34 | - unnecessary_null_aware_assignments
35 | - unnecessary_null_checks
36 | - unnecessary_nullable_for_final_variable_declarations
37 | - unnecessary_statements
38 | - use_late_for_private_fields_and_variables
39 | - use_named_constants
40 | - use_raw_strings
41 | - use_super_parameters
42 | - require_trailing_commas
43 |
--------------------------------------------------------------------------------
/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 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/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: cf4400006550b70f28e4b4af815151d1e74846c6
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | - require_trailing_commas
26 |
27 | # Additional information about this file can be found at
28 | # https://dart.dev/guides/language/analysis-options
29 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion flutter.compileSdkVersion
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | sourceSets {
41 | main.java.srcDirs += 'src/main/kotlin'
42 | }
43 |
44 | defaultConfig {
45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
46 | applicationId "com.example.example"
47 | minSdkVersion flutter.minSdkVersion
48 | targetSdkVersion flutter.targetSdkVersion
49 | versionCode flutterVersionCode.toInteger()
50 | versionName flutterVersionName
51 | }
52 |
53 | buildTypes {
54 | release {
55 | // TODO: Add your own signing config for the release build.
56 | // Signing with the debug keys for now, so `flutter run --release` works.
57 | signingConfig signingConfigs.debug
58 | }
59 | }
60 | }
61 |
62 | flutter {
63 | source '../..'
64 | }
65 |
66 | dependencies {
67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
68 | }
69 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.example
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/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-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/example/example.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/example/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 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/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 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | example
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 | CADisableMinimumFrameDurationOnPhone
47 |
48 | UIApplicationSupportsIndirectInputEvents
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import './showcase.dart';
4 | import './workspace.dart';
5 |
6 | void main() => runApp(const App());
7 |
8 | class App extends StatelessWidget {
9 | const App({Key? key}) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return MaterialApp(
14 | title: 'SpinKit Demo',
15 | debugShowCheckedModeBanner: false,
16 | theme: ThemeData(brightness: Brightness.dark),
17 | home: Scaffold(
18 | body: SafeArea(
19 | child: Stack(
20 | children: [
21 | Align(
22 | child: Builder(
23 | builder: (context) => IconButton(
24 | icon: const Icon(Icons.play_circle_filled),
25 | iconSize: 50.0,
26 | onPressed: () => Navigator.of(context).push(
27 | MaterialPageRoute(
28 | builder: (_) => const ShowCase(),
29 | fullscreenDialog: true,
30 | ),
31 | ),
32 | ),
33 | ),
34 | alignment: Alignment.bottomCenter,
35 | ),
36 | const Positioned.fill(child: Center(child: WorkSpace())),
37 | ],
38 | ),
39 | ),
40 | ),
41 | );
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/example/lib/showcase.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 |
4 | class ShowCase extends StatelessWidget {
5 | const ShowCase({Key? key}) : super(key: key);
6 |
7 | static const kits = [
8 | SpinKitRotatingCircle(color: Colors.white),
9 | SpinKitRotatingPlain(color: Colors.white),
10 | SpinKitChasingDots(color: Colors.white),
11 | SpinKitPumpingHeart(color: Colors.white),
12 | SpinKitPulse(color: Colors.white),
13 | SpinKitDoubleBounce(color: Colors.white),
14 | SpinKitWave(color: Colors.white, type: SpinKitWaveType.start),
15 | SpinKitWave(color: Colors.white, type: SpinKitWaveType.center),
16 | SpinKitWave(color: Colors.white, type: SpinKitWaveType.end),
17 | SpinKitPianoWave(color: Colors.white, type: SpinKitPianoWaveType.start),
18 | SpinKitPianoWave(color: Colors.white, type: SpinKitPianoWaveType.center),
19 | SpinKitPianoWave(color: Colors.white, type: SpinKitPianoWaveType.end),
20 | SpinKitThreeBounce(color: Colors.white),
21 | SpinKitThreeInOut(color: Colors.white),
22 | SpinKitWanderingCubes(color: Colors.white),
23 | SpinKitWanderingCubes(color: Colors.white, shape: BoxShape.circle),
24 | SpinKitCircle(color: Colors.white),
25 | SpinKitFadingFour(color: Colors.white),
26 | SpinKitFadingFour(color: Colors.white, shape: BoxShape.rectangle),
27 | SpinKitFadingCube(color: Colors.white),
28 | SpinKitCubeGrid(size: 51.0, color: Colors.white),
29 | SpinKitFoldingCube(color: Colors.white),
30 | SpinKitRing(color: Colors.white),
31 | SpinKitDualRing(color: Colors.white),
32 | SpinKitSpinningLines(color: Colors.white),
33 | SpinKitFadingGrid(color: Colors.white),
34 | SpinKitFadingGrid(color: Colors.white, shape: BoxShape.rectangle),
35 | SpinKitSquareCircle(color: Colors.white),
36 | SpinKitSpinningCircle(color: Colors.white),
37 | SpinKitSpinningCircle(color: Colors.white, shape: BoxShape.rectangle),
38 | SpinKitFadingCircle(color: Colors.white),
39 | SpinKitPulsingGrid(color: Colors.white),
40 | SpinKitPulsingGrid(color: Colors.white, boxShape: BoxShape.rectangle),
41 | SpinKitHourGlass(color: Colors.white),
42 | SpinKitPouringHourGlass(color: Colors.white),
43 | SpinKitPouringHourGlassRefined(color: Colors.white),
44 | SpinKitRipple(color: Colors.white),
45 | SpinKitDancingSquare(color: Colors.white),
46 | SpinKitWaveSpinner(color: Colors.white),
47 | ];
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | return Scaffold(
52 | appBar: AppBar(
53 | elevation: 0.0,
54 | backgroundColor: Colors.transparent,
55 | title: const Text('SpinKit', style: TextStyle(fontSize: 24.0)),
56 | ),
57 | body: GridView.builder(
58 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
59 | crossAxisCount: context.adaptiveCrossAxisCount,
60 | mainAxisSpacing: 46,
61 | childAspectRatio: 2,
62 | ),
63 | padding: const EdgeInsets.only(top: 32, bottom: 64),
64 | itemCount: kits.length,
65 | itemBuilder: (context, index) => kits[index],
66 | ),
67 | );
68 | }
69 | }
70 |
71 | extension on BuildContext {
72 | int get adaptiveCrossAxisCount {
73 | final width = MediaQuery.of(this).size.width;
74 | if (width > 1024) {
75 | return 8;
76 | } else if (width > 720 && width < 1024) {
77 | return 6;
78 | } else if (width > 480) {
79 | return 4;
80 | } else if (width > 320) {
81 | return 3;
82 | }
83 | return 1;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/example/lib/workspace.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 |
4 | class WorkSpace extends StatelessWidget {
5 | const WorkSpace({Key? key}) : super(key: key);
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return Container(
10 | color: Colors.white,
11 | width: 300.0,
12 | height: 300.0,
13 | child: SpinKitFadingCircle(
14 | itemBuilder: (_, int index) {
15 | return DecoratedBox(
16 | decoration: BoxDecoration(
17 | color: index.isEven ? Colors.red : Colors.green,
18 | ),
19 | );
20 | },
21 | size: 120.0,
22 | ),
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/example/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/dgph
7 | **/xcuserdata/
8 |
--------------------------------------------------------------------------------
/example/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "ephemeral/Flutter-Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "ephemeral/Flutter-Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/macos/Flutter/GeneratedPluginRegistrant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | import FlutterMacOS
6 | import Foundation
7 |
8 |
9 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
10 | }
11 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @NSApplicationMain
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "app_icon_16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "app_icon_32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "app_icon_32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "app_icon_64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "app_icon_128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "app_icon_256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "app_icon_256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "app_icon_512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "app_icon_512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "app_icon_1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = example
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved.
15 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/example/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 | com.apple.security.network.server
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/example/macos/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | $(PRODUCT_COPYRIGHT)
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/example/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | class MainFlutterWindow: NSWindow {
5 | override func awakeFromNib() {
6 | let flutterViewController = FlutterViewController.init()
7 | let windowFrame = self.frame
8 | self.contentViewController = flutterViewController
9 | self.setFrame(windowFrame, display: true)
10 |
11 | RegisterGeneratedPlugins(registry: flutterViewController)
12 |
13 | super.awakeFromNib()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/example/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: example
2 | description: A new Flutter project.
3 |
4 | publish_to: 'none'
5 |
6 | environment:
7 | sdk: ">=2.15.0 <3.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 |
13 | dev_dependencies:
14 | flutter_test:
15 | sdk: flutter
16 | flutter_spinkit:
17 | path: ../
18 | flutter_lints: ^1.0.4
19 |
20 | flutter:
21 | uses-material-design: true
22 |
--------------------------------------------------------------------------------
/example/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/web/favicon.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/web/icons/Icon-maskable-192.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/example/web/icons/Icon-maskable-512.png
--------------------------------------------------------------------------------
/example/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | example
33 |
34 |
35 |
36 |
39 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/example/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "short_name": "example",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | },
22 | {
23 | "src": "icons/Icon-maskable-192.png",
24 | "sizes": "192x192",
25 | "type": "image/png",
26 | "purpose": "maskable"
27 | },
28 | {
29 | "src": "icons/Icon-maskable-512.png",
30 | "sizes": "512x512",
31 | "type": "image/png",
32 | "purpose": "maskable"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/flutter_spinkit.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/lib/flutter_spinkit.dart:
--------------------------------------------------------------------------------
1 | library flutter_spinkit;
2 |
3 | export 'src/chasing_dots.dart';
4 | export 'src/circle.dart';
5 | export 'src/cube_grid.dart';
6 | export 'src/dancing_square.dart';
7 | export 'src/double_bounce.dart';
8 | export 'src/dual_ring.dart';
9 | export 'src/fading_circle.dart';
10 | export 'src/fading_cube.dart';
11 | export 'src/fading_four.dart';
12 | export 'src/fading_grid.dart';
13 | export 'src/folding_cube.dart';
14 | export 'src/hour_glass.dart';
15 | export 'src/piano_wave.dart';
16 | export 'src/pouring_hour_glass.dart';
17 | export 'src/pouring_hour_glass_refined.dart';
18 | export 'src/pulse.dart';
19 | export 'src/pulsing_grid.dart';
20 | export 'src/pumping_heart.dart';
21 | export 'src/ring.dart';
22 | export 'src/ripple.dart';
23 | export 'src/rotating_circle.dart';
24 | export 'src/rotating_plain.dart';
25 | export 'src/spinning_circle.dart';
26 | export 'src/spinning_lines.dart';
27 | export 'src/square_circle.dart';
28 | export 'src/three_bounce.dart';
29 | export 'src/three_in_out.dart';
30 | export 'src/wandering_cubes.dart';
31 | export 'src/wave.dart';
32 | export 'src/wave_spinner.dart';
33 |
--------------------------------------------------------------------------------
/lib/src/chasing_dots.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class SpinKitChasingDots extends StatefulWidget {
4 | const SpinKitChasingDots({
5 | Key? key,
6 | this.color,
7 | this.size = 50.0,
8 | this.itemBuilder,
9 | this.duration = const Duration(milliseconds: 2000),
10 | }) : assert(
11 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
12 | 'You should specify either a itemBuilder or a color',
13 | ),
14 | super(key: key);
15 |
16 | final Color? color;
17 | final double size;
18 | final IndexedWidgetBuilder? itemBuilder;
19 | final Duration duration;
20 |
21 | @override
22 | State createState() => _SpinKitChasingDotsState();
23 | }
24 |
25 | class _SpinKitChasingDotsState extends State with TickerProviderStateMixin {
26 | late AnimationController _scaleCtrl;
27 | late AnimationController _rotateCtrl;
28 | late Animation _scale;
29 | late Animation _rotate;
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 |
35 | _scaleCtrl = AnimationController(vsync: this, duration: widget.duration)
36 | ..addListener(() {
37 | if (mounted) {
38 | setState(() {});
39 | }
40 | })
41 | ..repeat(reverse: true);
42 | _scale = Tween(begin: -1.0, end: 1.0).animate(
43 | CurvedAnimation(parent: _scaleCtrl, curve: Curves.easeInOut),
44 | );
45 |
46 | _rotateCtrl = AnimationController(vsync: this, duration: widget.duration)
47 | ..addListener(() => setState(() {}))
48 | ..repeat();
49 | _rotate = Tween(begin: 0.0, end: 360.0).animate(
50 | CurvedAnimation(parent: _rotateCtrl, curve: Curves.linear),
51 | );
52 | }
53 |
54 | @override
55 | void dispose() {
56 | _scaleCtrl.dispose();
57 | _rotateCtrl.dispose();
58 | super.dispose();
59 | }
60 |
61 | @override
62 | Widget build(BuildContext context) {
63 | return Center(
64 | child: SizedBox.fromSize(
65 | size: Size.square(widget.size),
66 | child: Transform.rotate(
67 | angle: _rotate.value * 0.0174533,
68 | child: Stack(
69 | children: [
70 | Positioned(top: 0.0, child: _circle(1.0 - _scale.value.abs(), 0)),
71 | Positioned(bottom: 0.0, child: _circle(_scale.value.abs(), 1)),
72 | ],
73 | ),
74 | ),
75 | ),
76 | );
77 | }
78 |
79 | Widget _circle(double scale, int index) {
80 | return Transform.scale(
81 | scale: scale,
82 | child: SizedBox.fromSize(
83 | size: Size.square(widget.size * 0.6),
84 | child: widget.itemBuilder != null
85 | ? widget.itemBuilder!(context, index)
86 | : DecoratedBox(
87 | decoration: BoxDecoration(
88 | shape: BoxShape.circle,
89 | color: widget.color,
90 | ),
91 | ),
92 | ),
93 | );
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/lib/src/circle.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_spinkit/src/tweens/delay_tween.dart';
3 |
4 | class SpinKitCircle extends StatefulWidget {
5 | const SpinKitCircle({
6 | Key? key,
7 | this.color,
8 | this.size = 50.0,
9 | this.itemBuilder,
10 | this.duration = const Duration(milliseconds: 1200),
11 | this.controller,
12 | }) : assert(
13 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
14 | 'You should specify either a itemBuilder or a color',
15 | ),
16 | super(key: key);
17 |
18 | final Color? color;
19 | final double size;
20 | final IndexedWidgetBuilder? itemBuilder;
21 | final Duration duration;
22 | final AnimationController? controller;
23 |
24 | @override
25 | State createState() => _SpinKitCircleState();
26 | }
27 |
28 | class _SpinKitCircleState extends State with SingleTickerProviderStateMixin {
29 | static const _itemCount = 12;
30 |
31 | late AnimationController _controller;
32 |
33 | @override
34 | void initState() {
35 | super.initState();
36 |
37 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
38 | }
39 |
40 | @override
41 | void dispose() {
42 | if (widget.controller == null) {
43 | _controller.dispose();
44 | }
45 | super.dispose();
46 | }
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return Center(
51 | child: SizedBox.fromSize(
52 | size: Size.square(widget.size),
53 | child: Stack(
54 | children: List.generate(_itemCount, (index) {
55 | final position = widget.size * .5;
56 | return Positioned.fill(
57 | left: position,
58 | top: position,
59 | child: Transform(
60 | transform: Matrix4.rotationZ(30.0 * index * 0.0174533),
61 | child: Align(
62 | alignment: Alignment.center,
63 | child: ScaleTransition(
64 | scale: DelayTween(
65 | begin: 0.0,
66 | end: 1.0,
67 | delay: index / _itemCount,
68 | ).animate(_controller),
69 | child: SizedBox.fromSize(
70 | size: Size.square(widget.size * 0.15),
71 | child: _itemBuilder(index),
72 | ),
73 | ),
74 | ),
75 | ),
76 | );
77 | }),
78 | ),
79 | ),
80 | );
81 | }
82 |
83 | Widget _itemBuilder(int index) => widget.itemBuilder != null
84 | ? widget.itemBuilder!(context, index)
85 | : DecoratedBox(
86 | decoration: BoxDecoration(
87 | color: widget.color,
88 | shape: BoxShape.circle,
89 | ),
90 | );
91 | }
92 |
--------------------------------------------------------------------------------
/lib/src/double_bounce.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class SpinKitDoubleBounce extends StatefulWidget {
4 | const SpinKitDoubleBounce({
5 | Key? key,
6 | this.color,
7 | this.size = 50.0,
8 | this.itemBuilder,
9 | this.duration = const Duration(milliseconds: 2000),
10 | this.controller,
11 | }) : assert(
12 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
13 | 'You should specify either a itemBuilder or a color',
14 | ),
15 | super(key: key);
16 |
17 | final Color? color;
18 | final double size;
19 | final IndexedWidgetBuilder? itemBuilder;
20 | final Duration duration;
21 | final AnimationController? controller;
22 |
23 | @override
24 | State createState() => _SpinKitDoubleBounceState();
25 | }
26 |
27 | class _SpinKitDoubleBounceState extends State with SingleTickerProviderStateMixin {
28 | late AnimationController _controller;
29 | late Animation _animation;
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 |
35 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
36 | ..addListener(() {
37 | if (mounted) {
38 | setState(() {});
39 | }
40 | })
41 | ..repeat(reverse: true);
42 | _animation = Tween(begin: -1.0, end: 1.0).animate(
43 | CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
44 | );
45 | }
46 |
47 | @override
48 | void dispose() {
49 | if (widget.controller == null) {
50 | _controller.dispose();
51 | }
52 | super.dispose();
53 | }
54 |
55 | @override
56 | Widget build(BuildContext context) {
57 | return Center(
58 | child: Stack(
59 | children: List.generate(2, (i) {
60 | return Transform.scale(
61 | scale: (1.0 - i - _animation.value.abs()).abs(),
62 | child: SizedBox.fromSize(
63 | size: Size.square(widget.size),
64 | child: _itemBuilder(i),
65 | ),
66 | );
67 | }),
68 | ),
69 | );
70 | }
71 |
72 | Widget _itemBuilder(int index) => widget.itemBuilder != null
73 | ? widget.itemBuilder!(context, index)
74 | : DecoratedBox(
75 | decoration: BoxDecoration(
76 | shape: BoxShape.circle,
77 | color: widget.color!.withOpacity(0.6),
78 | ),
79 | );
80 | }
81 |
--------------------------------------------------------------------------------
/lib/src/dual_ring.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math;
2 |
3 | import 'package:flutter/widgets.dart';
4 |
5 | class SpinKitDualRing extends StatefulWidget {
6 | const SpinKitDualRing({
7 | Key? key,
8 | required this.color,
9 | this.lineWidth = 7.0,
10 | this.size = 50.0,
11 | this.duration = const Duration(milliseconds: 1200),
12 | this.controller,
13 | }) : super(key: key);
14 |
15 | final Color color;
16 | final double lineWidth;
17 | final double size;
18 | final Duration duration;
19 | final AnimationController? controller;
20 |
21 | @override
22 | State createState() => _SpinKitDualRingState();
23 | }
24 |
25 | class _SpinKitDualRingState extends State with SingleTickerProviderStateMixin {
26 | late AnimationController _controller;
27 | late Animation _animation;
28 |
29 | @override
30 | void initState() {
31 | super.initState();
32 |
33 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
34 | ..addListener(() {
35 | if (mounted) {
36 | setState(() {});
37 | }
38 | })
39 | ..repeat();
40 | _animation = Tween(begin: 0.0, end: 1.0).animate(
41 | CurvedAnimation(
42 | parent: _controller,
43 | curve: const Interval(0.0, 1.0, curve: Curves.linear),
44 | ),
45 | );
46 | }
47 |
48 | @override
49 | void dispose() {
50 | if (widget.controller == null) {
51 | _controller.dispose();
52 | }
53 | super.dispose();
54 | }
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | return Center(
59 | child: Transform(
60 | transform: Matrix4.identity()..rotateZ((_animation.value) * math.pi * 2),
61 | alignment: FractionalOffset.center,
62 | child: CustomPaint(
63 | painter: _DualRingPainter(
64 | angle: 90,
65 | paintWidth: widget.lineWidth,
66 | color: widget.color,
67 | ),
68 | child: SizedBox.fromSize(size: Size.square(widget.size)),
69 | ),
70 | ),
71 | );
72 | }
73 | }
74 |
75 | class _DualRingPainter extends CustomPainter {
76 | _DualRingPainter({
77 | required this.angle,
78 | required double paintWidth,
79 | required Color color,
80 | }) : ringPaint = Paint()
81 | ..color = color
82 | ..strokeWidth = paintWidth
83 | ..style = PaintingStyle.stroke;
84 |
85 | final Paint ringPaint;
86 | final double angle;
87 |
88 | @override
89 | void paint(Canvas canvas, Size size) {
90 | final rect = Rect.fromPoints(Offset.zero, Offset(size.width, size.height));
91 | canvas.drawArc(rect, 0.0, getRadian(angle), false, ringPaint);
92 | canvas.drawArc(rect, getRadian(180.0), getRadian(angle), false, ringPaint);
93 | }
94 |
95 | @override
96 | bool shouldRepaint(CustomPainter oldDelegate) => true;
97 |
98 | double getRadian(double angle) => math.pi / 180 * angle;
99 | }
100 |
--------------------------------------------------------------------------------
/lib/src/fading_circle.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_spinkit/src/tweens/delay_tween.dart';
3 |
4 | class SpinKitFadingCircle extends StatefulWidget {
5 | const SpinKitFadingCircle({
6 | Key? key,
7 | this.color,
8 | this.size = 50.0,
9 | this.itemSize,
10 | this.itemCount,
11 | this.itemBuilder,
12 | this.duration = const Duration(milliseconds: 1200),
13 | this.controller,
14 | }) : assert(
15 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
16 | 'You should specify either a itemBuilder or a color',
17 | ),
18 | super(key: key);
19 |
20 | final Color? color;
21 | final double size;
22 | final double? itemSize;
23 | final int? itemCount;
24 | final IndexedWidgetBuilder? itemBuilder;
25 | final Duration duration;
26 | final AnimationController? controller;
27 |
28 | @override
29 | State createState() => _SpinKitFadingCircleState();
30 | }
31 |
32 | class _SpinKitFadingCircleState extends State with SingleTickerProviderStateMixin {
33 | late AnimationController _controller;
34 |
35 | @override
36 | void initState() {
37 | super.initState();
38 |
39 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
40 | }
41 |
42 | @override
43 | void dispose() {
44 | if (widget.controller == null) {
45 | _controller.dispose();
46 | }
47 | super.dispose();
48 | }
49 |
50 | @override
51 | Widget build(BuildContext context) {
52 | final itemSize = widget.itemSize ?? widget.size * 0.15;
53 | final itemCount = widget.itemCount ?? 12;
54 |
55 | return Center(
56 | child: SizedBox.fromSize(
57 | size: Size.square(widget.size),
58 | child: Stack(
59 | children: List.generate(itemCount, (i) {
60 | final position = widget.size * .5;
61 | return Positioned.fill(
62 | left: position,
63 | top: position,
64 | child: Transform(
65 | transform: Matrix4.rotationZ((360 / itemCount) * i * 0.0174533),
66 | child: Align(
67 | alignment: Alignment.center,
68 | child: FadeTransition(
69 | opacity: DelayTween(
70 | begin: 0.0,
71 | end: 1.0,
72 | delay: i / itemCount,
73 | ).animate(_controller),
74 | child: SizedBox.fromSize(
75 | size: Size.square(itemSize),
76 | child: _itemBuilder(i),
77 | ),
78 | ),
79 | ),
80 | ),
81 | );
82 | }),
83 | ),
84 | ),
85 | );
86 | }
87 |
88 | Widget _itemBuilder(int index) => widget.itemBuilder != null
89 | ? widget.itemBuilder!(context, index)
90 | : DecoratedBox(
91 | decoration: BoxDecoration(
92 | color: widget.color,
93 | shape: BoxShape.circle,
94 | ),
95 | );
96 | }
97 |
--------------------------------------------------------------------------------
/lib/src/fading_cube.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_spinkit/src/tweens/delay_tween.dart';
3 |
4 | class SpinKitFadingCube extends StatefulWidget {
5 | const SpinKitFadingCube({
6 | Key? key,
7 | this.color,
8 | this.size = 50.0,
9 | this.itemBuilder,
10 | this.duration = const Duration(milliseconds: 2400),
11 | this.controller,
12 | }) : assert(
13 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
14 | 'You should specify either a itemBuilder or a color',
15 | ),
16 | super(key: key);
17 |
18 | final Color? color;
19 | final double size;
20 | final IndexedWidgetBuilder? itemBuilder;
21 | final Duration duration;
22 | final AnimationController? controller;
23 |
24 | @override
25 | State createState() => _SpinKitFadingCubeState();
26 | }
27 |
28 | class _SpinKitFadingCubeState extends State with SingleTickerProviderStateMixin {
29 | late AnimationController _controller;
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 |
35 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
36 | }
37 |
38 | @override
39 | void dispose() {
40 | if (widget.controller == null) {
41 | _controller.dispose();
42 | }
43 | super.dispose();
44 | }
45 |
46 | @override
47 | Widget build(BuildContext context) {
48 | return Center(
49 | child: SizedBox.fromSize(
50 | size: Size.square(widget.size),
51 | child: Center(
52 | child: Transform.rotate(
53 | angle: -45.0 * 0.0174533,
54 | child: Stack(
55 | children: List.generate(4, (i) {
56 | final size = widget.size * 0.5, position = widget.size * .5;
57 | return Positioned.fill(
58 | top: position,
59 | left: position,
60 | child: Transform.scale(
61 | scale: 1.1,
62 | origin: Offset(-size * .5, -size * .5),
63 | child: Transform(
64 | transform: Matrix4.rotationZ(90.0 * i * 0.0174533),
65 | child: Align(
66 | alignment: Alignment.center,
67 | child: FadeTransition(
68 | opacity: DelayTween(
69 | begin: 0.0,
70 | end: 1.0,
71 | delay: 0.3 * i,
72 | ).animate(_controller),
73 | child: SizedBox.fromSize(
74 | size: Size.square(size),
75 | child: _itemBuilder(i),
76 | ),
77 | ),
78 | ),
79 | ),
80 | ),
81 | );
82 | }),
83 | ),
84 | ),
85 | ),
86 | ),
87 | );
88 | }
89 |
90 | Widget _itemBuilder(int index) => widget.itemBuilder != null
91 | ? widget.itemBuilder!(context, index)
92 | : DecoratedBox(decoration: BoxDecoration(color: widget.color));
93 | }
94 |
--------------------------------------------------------------------------------
/lib/src/fading_four.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_spinkit/src/tweens/delay_tween.dart';
3 |
4 | class SpinKitFadingFour extends StatefulWidget {
5 | const SpinKitFadingFour({
6 | Key? key,
7 | this.color,
8 | this.shape = BoxShape.circle,
9 | this.size = 50.0,
10 | this.itemBuilder,
11 | this.duration = const Duration(milliseconds: 1200),
12 | this.controller,
13 | }) : assert(
14 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
15 | 'You should specify either a itemBuilder or a color',
16 | ),
17 | super(key: key);
18 |
19 | final Color? color;
20 | final BoxShape shape;
21 | final double size;
22 | final IndexedWidgetBuilder? itemBuilder;
23 | final Duration duration;
24 | final AnimationController? controller;
25 |
26 | @override
27 | State createState() => _SpinKitFadingFourState();
28 | }
29 |
30 | class _SpinKitFadingFourState extends State with SingleTickerProviderStateMixin {
31 | static const List _delays = [.0, -0.9, -0.6, -0.3];
32 | late AnimationController _controller;
33 |
34 | @override
35 | void initState() {
36 | super.initState();
37 |
38 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
39 | }
40 |
41 | @override
42 | void dispose() {
43 | if (widget.controller == null) {
44 | _controller.dispose();
45 | }
46 | super.dispose();
47 | }
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | return Center(
52 | child: SizedBox.fromSize(
53 | size: Size.square(widget.size),
54 | child: Stack(
55 | children: List.generate(4, (i) {
56 | final position = widget.size * .5;
57 | return Positioned.fill(
58 | left: position,
59 | top: position,
60 | child: Transform(
61 | transform: Matrix4.rotationZ(30.0 * (i * 3) * 0.0174533),
62 | child: Align(
63 | alignment: Alignment.center,
64 | child: FadeTransition(
65 | opacity: DelayTween(
66 | begin: 0.0,
67 | end: 1.0,
68 | delay: _delays[i],
69 | ).animate(_controller),
70 | child: SizedBox.fromSize(
71 | size: Size.square(widget.size * 0.25),
72 | child: _itemBuilder(i),
73 | ),
74 | ),
75 | ),
76 | ),
77 | );
78 | }),
79 | ),
80 | ),
81 | );
82 | }
83 |
84 | Widget _itemBuilder(int index) => widget.itemBuilder != null
85 | ? widget.itemBuilder!(context, index)
86 | : DecoratedBox(
87 | decoration: BoxDecoration(color: widget.color, shape: widget.shape),
88 | );
89 | }
90 |
--------------------------------------------------------------------------------
/lib/src/fading_grid.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_spinkit/src/tweens/delay_tween.dart';
3 |
4 | class SpinKitFadingGrid extends StatefulWidget {
5 | const SpinKitFadingGrid({
6 | Key? key,
7 | this.color,
8 | this.shape = BoxShape.circle,
9 | this.size = 50.0,
10 | this.itemBuilder,
11 | this.duration = const Duration(milliseconds: 1200),
12 | this.controller,
13 | }) : assert(
14 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
15 | 'You should specify either a itemBuilder or a color',
16 | ),
17 | super(key: key);
18 |
19 | final Color? color;
20 | final BoxShape shape;
21 | final double size;
22 | final IndexedWidgetBuilder? itemBuilder;
23 | final Duration duration;
24 | final AnimationController? controller;
25 |
26 | @override
27 | State createState() => _SpinKitFadingGridState();
28 | }
29 |
30 | class _SpinKitFadingGridState extends State with SingleTickerProviderStateMixin {
31 | late AnimationController _controller;
32 |
33 | @override
34 | void initState() {
35 | super.initState();
36 |
37 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
38 | }
39 |
40 | @override
41 | void dispose() {
42 | if (widget.controller == null) {
43 | _controller.dispose();
44 | }
45 | super.dispose();
46 | }
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return SizedBox.fromSize(
51 | size: Size.square(widget.size),
52 | child: Column(
53 | mainAxisAlignment: MainAxisAlignment.center,
54 | mainAxisSize: MainAxisSize.max,
55 | children: [
56 | Row(
57 | mainAxisSize: MainAxisSize.max,
58 | mainAxisAlignment: MainAxisAlignment.center,
59 | children: [
60 | _circle(0, 1),
61 | SizedBox(width: widget.size / 8),
62 | _circle(1, 1),
63 | SizedBox(width: widget.size / 8),
64 | _circle(2, 2),
65 | ],
66 | ),
67 | Row(
68 | mainAxisSize: MainAxisSize.max,
69 | mainAxisAlignment: MainAxisAlignment.center,
70 | children: [
71 | SizedBox(height: widget.size / 8, width: widget.size),
72 | ],
73 | ),
74 | Row(
75 | mainAxisSize: MainAxisSize.max,
76 | mainAxisAlignment: MainAxisAlignment.center,
77 | children: [
78 | _circle(3, 4),
79 | SizedBox(width: widget.size / 8),
80 | _circle(4, 1),
81 | SizedBox(width: widget.size / 8),
82 | _circle(5, 2),
83 | ],
84 | ),
85 | Row(
86 | mainAxisSize: MainAxisSize.max,
87 | mainAxisAlignment: MainAxisAlignment.center,
88 | children: [
89 | SizedBox(height: widget.size / 8, width: widget.size),
90 | ],
91 | ),
92 | Row(
93 | mainAxisSize: MainAxisSize.max,
94 | mainAxisAlignment: MainAxisAlignment.center,
95 | children: [
96 | _circle(6, 4),
97 | SizedBox(width: widget.size / 8),
98 | _circle(7, 3),
99 | SizedBox(width: widget.size / 8),
100 | _circle(8, 3),
101 | ],
102 | ),
103 | ],
104 | ),
105 | );
106 | }
107 |
108 | Widget _circle(int index, int i) {
109 | return FadeTransition(
110 | opacity: DelayTween(
111 | begin: 0.4,
112 | end: 0.9,
113 | delay: 0.3 * (i - 1),
114 | ).animate(_controller),
115 | child: SizedBox.fromSize(
116 | size: Size.square(widget.size / 4),
117 | child: _itemBuilder(index),
118 | ),
119 | );
120 | }
121 |
122 | Widget _itemBuilder(int index) => widget.itemBuilder != null
123 | ? widget.itemBuilder!(context, index)
124 | : DecoratedBox(
125 | decoration: BoxDecoration(color: widget.color, shape: widget.shape),
126 | );
127 | }
128 |
--------------------------------------------------------------------------------
/lib/src/hour_glass.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math;
2 |
3 | import 'package:flutter/widgets.dart';
4 |
5 | class SpinKitHourGlass extends StatefulWidget {
6 | const SpinKitHourGlass({
7 | Key? key,
8 | required this.color,
9 | this.size = 50.0,
10 | this.duration = const Duration(milliseconds: 1200),
11 | this.controller,
12 | }) : super(key: key);
13 |
14 | final Color color;
15 | final double size;
16 | final Duration duration;
17 | final AnimationController? controller;
18 |
19 | @override
20 | State createState() => _SpinKitHourGlassState();
21 | }
22 |
23 | class _SpinKitHourGlassState extends State with SingleTickerProviderStateMixin {
24 | late AnimationController _controller;
25 | late Animation _animation;
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 |
31 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
32 | ..addListener(() {
33 | if (mounted) {
34 | setState(() {});
35 | }
36 | })
37 | ..repeat();
38 | _animation = Tween(begin: 0.0, end: 8.0).animate(
39 | CurvedAnimation(
40 | parent: _controller,
41 | curve: const Interval(0.0, 1.0, curve: Curves.easeOut),
42 | ),
43 | );
44 | }
45 |
46 | @override
47 | void dispose() {
48 | if (widget.controller == null) {
49 | _controller.dispose();
50 | }
51 | super.dispose();
52 | }
53 |
54 | @override
55 | Widget build(BuildContext context) {
56 | return Center(
57 | child: Transform(
58 | transform: Matrix4.identity()..rotateZ((_animation.value) * math.pi),
59 | alignment: FractionalOffset.center,
60 | child: CustomPaint(
61 | painter: _HourGlassPainter(weight: 90, color: widget.color),
62 | child: SizedBox.fromSize(size: Size.square(widget.size)),
63 | ),
64 | ),
65 | );
66 | }
67 | }
68 |
69 | class _HourGlassPainter extends CustomPainter {
70 | _HourGlassPainter({required this.weight, required Color color})
71 | : _paint = Paint()
72 | ..color = color
73 | ..strokeWidth = 1.0;
74 |
75 | final Paint _paint;
76 | final double weight;
77 |
78 | @override
79 | void paint(Canvas canvas, Size size) {
80 | final rect = Rect.fromPoints(Offset.zero, Offset(size.width, size.height));
81 | canvas.drawArc(rect, 0.0, getRadian(weight), true, _paint);
82 | canvas.drawArc(rect, getRadian(180.0), getRadian(weight), true, _paint);
83 | }
84 |
85 | @override
86 | bool shouldRepaint(CustomPainter oldDelegate) => true;
87 |
88 | double getRadian(double angle) => math.pi / 180 * angle;
89 | }
90 |
--------------------------------------------------------------------------------
/lib/src/pulse.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class SpinKitPulse extends StatefulWidget {
4 | const SpinKitPulse({
5 | Key? key,
6 | this.color,
7 | this.size = 50.0,
8 | this.itemBuilder,
9 | this.duration = const Duration(seconds: 1),
10 | this.controller,
11 | }) : assert(
12 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
13 | 'You should specify either a itemBuilder or a color',
14 | ),
15 | super(key: key);
16 |
17 | final Color? color;
18 | final double size;
19 | final IndexedWidgetBuilder? itemBuilder;
20 | final Duration duration;
21 | final AnimationController? controller;
22 |
23 | @override
24 | State createState() => _SpinKitPulseState();
25 | }
26 |
27 | class _SpinKitPulseState extends State with SingleTickerProviderStateMixin {
28 | late AnimationController _controller;
29 | late Animation _animation;
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 |
35 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
36 | ..addListener(() {
37 | if (mounted) {
38 | setState(() {});
39 | }
40 | })
41 | ..repeat();
42 | _animation = CurveTween(curve: Curves.easeInOut).animate(_controller);
43 | }
44 |
45 | @override
46 | void dispose() {
47 | if (widget.controller == null) {
48 | _controller.dispose();
49 | }
50 | super.dispose();
51 | }
52 |
53 | @override
54 | Widget build(BuildContext context) {
55 | return Center(
56 | child: Opacity(
57 | opacity: 1.0 - _animation.value,
58 | child: Transform.scale(
59 | scale: _animation.value,
60 | child: SizedBox.fromSize(
61 | size: Size.square(widget.size),
62 | child: _itemBuilder(0),
63 | ),
64 | ),
65 | ),
66 | );
67 | }
68 |
69 | Widget _itemBuilder(int index) => widget.itemBuilder != null
70 | ? widget.itemBuilder!(context, index)
71 | : DecoratedBox(
72 | decoration: BoxDecoration(
73 | shape: BoxShape.circle,
74 | color: widget.color,
75 | ),
76 | );
77 | }
78 |
--------------------------------------------------------------------------------
/lib/src/pulsing_grid.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | import 'tweens/delay_tween.dart';
4 |
5 | class SpinKitPulsingGrid extends StatefulWidget {
6 | const SpinKitPulsingGrid({
7 | Key? key,
8 | this.color,
9 | this.size = 50.0,
10 | this.itemBuilder,
11 | this.duration = const Duration(milliseconds: 1500),
12 | this.boxShape,
13 | this.controller,
14 | }) : assert(
15 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
16 | 'You should specify either a itemBuilder or a color',
17 | ),
18 | super(key: key);
19 |
20 | final Color? color;
21 | final double size;
22 | final IndexedWidgetBuilder? itemBuilder;
23 | final Duration duration;
24 | final BoxShape? boxShape;
25 | final AnimationController? controller;
26 |
27 | @override
28 | State createState() => _SpinKitPulsingGridState();
29 | }
30 |
31 | class _SpinKitPulsingGridState extends State with SingleTickerProviderStateMixin {
32 | static const _gridCount = 3;
33 |
34 | late AnimationController _controller;
35 |
36 | @override
37 | void initState() {
38 | super.initState();
39 |
40 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
41 | }
42 |
43 | @override
44 | void dispose() {
45 | if (widget.controller == null) {
46 | _controller.dispose();
47 | }
48 | super.dispose();
49 | }
50 |
51 | @override
52 | Widget build(BuildContext context) {
53 | return Center(
54 | child: SizedBox.fromSize(
55 | size: Size.square(widget.size),
56 | child: Stack(
57 | children: List.generate(_gridCount * _gridCount, (i) {
58 | final row = (i / _gridCount).floor();
59 | final column = i % _gridCount;
60 | final mid = i == (_gridCount * _gridCount - 1) / 2;
61 | final position = widget.size * .7;
62 | final delay = mid
63 | ? .25
64 | : i.isOdd
65 | ? .5
66 | : .75;
67 |
68 | return Positioned.fill(
69 | left: position * (-1 + column),
70 | top: position * (-1 + row),
71 | child: Align(
72 | alignment: Alignment.center,
73 | child: ScaleTransition(
74 | scale: CurvedAnimation(
75 | parent: DelayTween(
76 | begin: 0.0,
77 | end: 1.0,
78 | delay: delay,
79 | ).animate(_controller),
80 | curve: Curves.easeOut,
81 | ),
82 | child: SizedBox.fromSize(
83 | size: Size.square(widget.size / 4),
84 | child: _itemBuilder(i),
85 | ),
86 | ),
87 | ),
88 | );
89 | }),
90 | ),
91 | ),
92 | );
93 | }
94 |
95 | Widget _itemBuilder(int index) => widget.itemBuilder != null
96 | ? widget.itemBuilder!(context, index)
97 | : DecoratedBox(
98 | decoration: BoxDecoration(
99 | color: widget.color,
100 | shape: widget.boxShape ?? BoxShape.circle,
101 | ),
102 | );
103 | }
104 |
--------------------------------------------------------------------------------
/lib/src/pumping_heart.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math show pow;
2 |
3 | import 'package:flutter/material.dart' show Icons;
4 | import 'package:flutter/widgets.dart';
5 |
6 | class SpinKitPumpingHeart extends StatefulWidget {
7 | const SpinKitPumpingHeart({
8 | Key? key,
9 | this.color,
10 | this.size = 50.0,
11 | this.itemBuilder,
12 | this.duration = const Duration(milliseconds: 2400),
13 | this.controller,
14 | }) : assert(
15 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
16 | 'You should specify either a itemBuilder or a color',
17 | ),
18 | super(key: key);
19 |
20 | final Color? color;
21 | final double size;
22 | final IndexedWidgetBuilder? itemBuilder;
23 | final Duration duration;
24 | final AnimationController? controller;
25 |
26 | @override
27 | State createState() => _SpinKitPumpingHeartState();
28 | }
29 |
30 | class _SpinKitPumpingHeartState extends State with SingleTickerProviderStateMixin {
31 | late AnimationController _controller;
32 | late Animation _animation;
33 |
34 | @override
35 | void initState() {
36 | super.initState();
37 |
38 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
39 | _animation = Tween(begin: 1.0, end: 1.25).animate(
40 | CurvedAnimation(
41 | parent: _controller,
42 | curve: const Interval(0.0, 1.0, curve: SpinKitPumpCurve()),
43 | ),
44 | );
45 | }
46 |
47 | @override
48 | void dispose() {
49 | if (widget.controller == null) {
50 | _controller.dispose();
51 | }
52 | super.dispose();
53 | }
54 |
55 | @override
56 | Widget build(BuildContext context) {
57 | return ScaleTransition(scale: _animation, child: _itemBuilder(0));
58 | }
59 |
60 | Widget _itemBuilder(int index) => widget.itemBuilder != null
61 | ? widget.itemBuilder!(context, index)
62 | : Icon(Icons.favorite, color: widget.color, size: widget.size);
63 | }
64 |
65 | class SpinKitPumpCurve extends Curve {
66 | const SpinKitPumpCurve();
67 |
68 | static const magicNumber = 4.54545454;
69 |
70 | @override
71 | double transform(double t) {
72 | if (t >= 0.0 && t < 0.22) {
73 | return math.pow(t, 1.0) * magicNumber;
74 | } else if (t >= 0.22 && t < 0.44) {
75 | return 1.0 - (math.pow(t - 0.22, 1.0) * magicNumber);
76 | } else if (t >= 0.44 && t < 0.5) {
77 | return 0.0;
78 | } else if (t >= 0.5 && t < 0.72) {
79 | return math.pow(t - 0.5, 1.0) * (magicNumber / 2);
80 | } else if (t >= 0.72 && t < 0.94) {
81 | return 0.5 - (math.pow(t - 0.72, 1.0) * (magicNumber / 2));
82 | }
83 | return 0.0;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/lib/src/ring.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/widgets.dart';
4 |
5 | class SpinKitRing extends StatefulWidget {
6 | const SpinKitRing({
7 | Key? key,
8 | required this.color,
9 | this.lineWidth = 7.0,
10 | this.size = 50.0,
11 | this.duration = const Duration(milliseconds: 1200),
12 | this.controller,
13 | }) : super(key: key);
14 |
15 | final Color color;
16 | final double size;
17 | final double lineWidth;
18 | final Duration duration;
19 | final AnimationController? controller;
20 |
21 | @override
22 | State createState() => _SpinKitRingState();
23 | }
24 |
25 | class _SpinKitRingState extends State with SingleTickerProviderStateMixin {
26 | late AnimationController _controller;
27 | late Animation _animation1;
28 | late Animation _animation2;
29 | late Animation _animation3;
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 |
35 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
36 | ..addListener(() {
37 | if (mounted) {
38 | setState(() {});
39 | }
40 | })
41 | ..repeat();
42 | _animation1 = Tween(begin: 0.0, end: 1.0).animate(
43 | CurvedAnimation(
44 | parent: _controller,
45 | curve: const Interval(0.0, 1.0, curve: Curves.linear),
46 | ),
47 | );
48 | _animation2 = Tween(begin: -2 / 3, end: 1 / 2).animate(
49 | CurvedAnimation(
50 | parent: _controller,
51 | curve: const Interval(0.5, 1.0, curve: Curves.linear),
52 | ),
53 | );
54 | _animation3 = Tween(begin: 0.25, end: 5 / 6).animate(
55 | CurvedAnimation(
56 | parent: _controller,
57 | curve: const Interval(0.0, 1.0, curve: SpinKitRingCurve()),
58 | ),
59 | );
60 | }
61 |
62 | @override
63 | void dispose() {
64 | if (widget.controller == null) {
65 | _controller.dispose();
66 | }
67 | super.dispose();
68 | }
69 |
70 | @override
71 | Widget build(BuildContext context) {
72 | return Center(
73 | child: Transform(
74 | transform: Matrix4.identity()..rotateZ((_animation1.value) * 5 * pi / 6),
75 | alignment: FractionalOffset.center,
76 | child: SizedBox.fromSize(
77 | size: Size.square(widget.size),
78 | child: CustomPaint(
79 | foregroundPainter: RingPainter(
80 | paintWidth: widget.lineWidth,
81 | trackColor: widget.color,
82 | progressPercent: _animation3.value,
83 | startAngle: pi * _animation2.value,
84 | ),
85 | ),
86 | ),
87 | ),
88 | );
89 | }
90 | }
91 |
92 | class RingPainter extends CustomPainter {
93 | RingPainter({
94 | required this.paintWidth,
95 | this.progressPercent,
96 | this.startAngle,
97 | required this.trackColor,
98 | }) : trackPaint = Paint()
99 | ..color = trackColor
100 | ..style = PaintingStyle.stroke
101 | ..strokeWidth = paintWidth
102 | ..strokeCap = StrokeCap.square;
103 |
104 | final double paintWidth;
105 | final Paint trackPaint;
106 | final Color trackColor;
107 | final double? progressPercent;
108 | final double? startAngle;
109 |
110 | @override
111 | void paint(Canvas canvas, Size size) {
112 | final center = Offset(size.width / 2, size.height / 2);
113 | final radius = (min(size.width, size.height) - paintWidth) / 2;
114 | canvas.drawArc(
115 | Rect.fromCircle(center: center, radius: radius),
116 | startAngle!,
117 | 2 * pi * progressPercent!,
118 | false,
119 | trackPaint,
120 | );
121 | }
122 |
123 | @override
124 | bool shouldRepaint(CustomPainter oldDelegate) => true;
125 | }
126 |
127 | class SpinKitRingCurve extends Curve {
128 | const SpinKitRingCurve();
129 |
130 | @override
131 | double transform(double t) => (t <= 0.5) ? 2 * t : 2 * (1 - t);
132 | }
133 |
--------------------------------------------------------------------------------
/lib/src/ripple.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class SpinKitRipple extends StatefulWidget {
4 | const SpinKitRipple({
5 | Key? key,
6 | this.color,
7 | this.size = 50.0,
8 | this.borderWidth = 6.0,
9 | this.itemBuilder,
10 | this.duration = const Duration(milliseconds: 1800),
11 | this.controller,
12 | }) : assert(
13 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
14 | 'You should specify either a itemBuilder or a color',
15 | ),
16 | super(key: key);
17 |
18 | final Color? color;
19 | final double size;
20 | final double borderWidth;
21 | final IndexedWidgetBuilder? itemBuilder;
22 | final Duration duration;
23 | final AnimationController? controller;
24 |
25 | @override
26 | State createState() => _SpinKitRippleState();
27 | }
28 |
29 | class _SpinKitRippleState extends State with SingleTickerProviderStateMixin {
30 | late AnimationController _controller;
31 | late Animation _animation1;
32 | late Animation _animation2;
33 |
34 | @override
35 | void initState() {
36 | super.initState();
37 |
38 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
39 | ..addListener(() {
40 | if (mounted) {
41 | setState(() {});
42 | }
43 | })
44 | ..repeat();
45 | _animation1 = Tween(begin: 0.0, end: 1.0).animate(
46 | CurvedAnimation(
47 | parent: _controller,
48 | curve: const Interval(0.0, 0.75, curve: Curves.linear),
49 | ),
50 | );
51 | _animation2 = Tween(begin: 0.0, end: 1.0).animate(
52 | CurvedAnimation(
53 | parent: _controller,
54 | curve: const Interval(0.25, 1.0, curve: Curves.linear),
55 | ),
56 | );
57 | }
58 |
59 | @override
60 | void dispose() {
61 | if (widget.controller == null) {
62 | _controller.dispose();
63 | }
64 | super.dispose();
65 | }
66 |
67 | @override
68 | Widget build(BuildContext context) {
69 | return Center(
70 | child: Stack(
71 | children: [
72 | Opacity(
73 | opacity: 1.0 - _animation1.value,
74 | child: Transform.scale(
75 | scale: _animation1.value,
76 | child: _itemBuilder(0),
77 | ),
78 | ),
79 | Opacity(
80 | opacity: 1.0 - _animation2.value,
81 | child: Transform.scale(
82 | scale: _animation2.value,
83 | child: _itemBuilder(1),
84 | ),
85 | ),
86 | ],
87 | ),
88 | );
89 | }
90 |
91 | Widget _itemBuilder(int index) {
92 | return SizedBox.fromSize(
93 | size: Size.square(widget.size),
94 | child: widget.itemBuilder != null
95 | ? widget.itemBuilder!(context, index)
96 | : DecoratedBox(
97 | decoration: BoxDecoration(
98 | shape: BoxShape.circle,
99 | border: Border.all(
100 | color: widget.color!,
101 | width: widget.borderWidth,
102 | ),
103 | ),
104 | ),
105 | );
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/lib/src/rotating_circle.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class SpinKitRotatingCircle extends StatefulWidget {
4 | const SpinKitRotatingCircle({
5 | Key? key,
6 | this.color,
7 | this.size = 50.0,
8 | this.itemBuilder,
9 | this.duration = const Duration(milliseconds: 1200),
10 | this.controller,
11 | }) : assert(
12 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
13 | 'You should specify either a itemBuilder or a color',
14 | ),
15 | super(key: key);
16 |
17 | final Color? color;
18 | final double size;
19 | final IndexedWidgetBuilder? itemBuilder;
20 | final Duration duration;
21 | final AnimationController? controller;
22 |
23 | @override
24 | State createState() => _SpinKitRotatingCircleState();
25 | }
26 |
27 | class _SpinKitRotatingCircleState extends State with SingleTickerProviderStateMixin {
28 | late AnimationController _controller;
29 | late Animation _animation1;
30 | late Animation _animation2;
31 |
32 | @override
33 | void initState() {
34 | super.initState();
35 |
36 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
37 | ..addListener(() {
38 | if (mounted) {
39 | setState(() {});
40 | }
41 | })
42 | ..repeat();
43 | _animation1 = Tween(begin: 0.0, end: 180.0).animate(
44 | CurvedAnimation(
45 | parent: _controller,
46 | curve: const Interval(0.0, 0.5, curve: Curves.easeIn),
47 | ),
48 | );
49 | _animation2 = Tween(begin: 0.0, end: 180.0).animate(
50 | CurvedAnimation(
51 | parent: _controller,
52 | curve: const Interval(0.5, 1.0, curve: Curves.easeOut),
53 | ),
54 | );
55 | }
56 |
57 | @override
58 | void dispose() {
59 | if (widget.controller == null) {
60 | _controller.dispose();
61 | }
62 | super.dispose();
63 | }
64 |
65 | @override
66 | Widget build(BuildContext context) {
67 | return Center(
68 | child: Transform(
69 | transform: Matrix4.identity()
70 | ..rotateX((0 - _animation1.value) * 0.0174533)
71 | ..rotateY((0 - _animation2.value) * 0.0174533),
72 | alignment: FractionalOffset.center,
73 | child: SizedBox.fromSize(
74 | size: Size.square(widget.size),
75 | child: _itemBuilder(0),
76 | ),
77 | ),
78 | );
79 | }
80 |
81 | Widget _itemBuilder(int index) => widget.itemBuilder != null
82 | ? widget.itemBuilder!(context, index)
83 | : DecoratedBox(
84 | decoration: BoxDecoration(
85 | color: widget.color,
86 | shape: BoxShape.circle,
87 | ),
88 | );
89 | }
90 |
--------------------------------------------------------------------------------
/lib/src/rotating_plain.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class SpinKitRotatingPlain extends StatefulWidget {
4 | const SpinKitRotatingPlain({
5 | Key? key,
6 | this.color,
7 | this.size = 50.0,
8 | this.itemBuilder,
9 | this.duration = const Duration(milliseconds: 1200),
10 | this.controller,
11 | }) : assert(
12 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
13 | 'You should specify either a itemBuilder or a color',
14 | ),
15 | super(key: key);
16 |
17 | final Color? color;
18 | final double size;
19 | final IndexedWidgetBuilder? itemBuilder;
20 | final Duration duration;
21 | final AnimationController? controller;
22 |
23 | @override
24 | State createState() => _SpinKitRotatingPlainState();
25 | }
26 |
27 | class _SpinKitRotatingPlainState extends State with SingleTickerProviderStateMixin {
28 | late AnimationController _controller;
29 | late Animation _animation1;
30 | late Animation _animation2;
31 |
32 | @override
33 | void initState() {
34 | super.initState();
35 |
36 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
37 | ..addListener(() {
38 | if (mounted) {
39 | setState(() {});
40 | }
41 | })
42 | ..repeat();
43 | _animation1 = Tween(begin: 0.0, end: 180.0).animate(
44 | CurvedAnimation(
45 | parent: _controller,
46 | curve: const Interval(0.0, 0.5, curve: Curves.easeIn),
47 | ),
48 | );
49 | _animation2 = Tween(begin: 0.0, end: 180.0).animate(
50 | CurvedAnimation(
51 | parent: _controller,
52 | curve: const Interval(0.5, 1.0, curve: Curves.easeOut),
53 | ),
54 | );
55 | }
56 |
57 | @override
58 | void dispose() {
59 | if (widget.controller == null) {
60 | _controller.dispose();
61 | }
62 | super.dispose();
63 | }
64 |
65 | @override
66 | Widget build(BuildContext context) {
67 | return Center(
68 | child: Transform(
69 | transform: Matrix4.identity()
70 | ..rotateX((0 - _animation1.value) * 0.0174533)
71 | ..rotateY((0 - _animation2.value) * 0.0174533),
72 | alignment: FractionalOffset.center,
73 | child: SizedBox.fromSize(
74 | size: Size.square(widget.size),
75 | child: _itemBuilder(0),
76 | ),
77 | ),
78 | );
79 | }
80 |
81 | Widget _itemBuilder(int index) => widget.itemBuilder != null
82 | ? widget.itemBuilder!(context, index)
83 | : DecoratedBox(decoration: BoxDecoration(color: widget.color));
84 | }
85 |
--------------------------------------------------------------------------------
/lib/src/spinning_circle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/widgets.dart';
4 |
5 | class SpinKitSpinningCircle extends StatefulWidget {
6 | const SpinKitSpinningCircle({
7 | Key? key,
8 | this.color,
9 | this.shape = BoxShape.circle,
10 | this.size = 50.0,
11 | this.itemBuilder,
12 | this.duration = const Duration(milliseconds: 1200),
13 | this.controller,
14 | }) : assert(
15 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
16 | 'You should specify either a itemBuilder or a color',
17 | ),
18 | super(key: key);
19 |
20 | final Color? color;
21 | final BoxShape shape;
22 | final double size;
23 | final IndexedWidgetBuilder? itemBuilder;
24 | final Duration duration;
25 | final AnimationController? controller;
26 |
27 | @override
28 | State createState() => _SpinKitSpinningCircleState();
29 | }
30 |
31 | class _SpinKitSpinningCircleState extends State with SingleTickerProviderStateMixin {
32 | late AnimationController _controller;
33 | late Animation _animation;
34 |
35 | @override
36 | void initState() {
37 | super.initState();
38 |
39 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
40 | ..addListener(() {
41 | if (mounted) {
42 | setState(() {});
43 | }
44 | })
45 | ..repeat();
46 | _animation = Tween(begin: 0.0, end: 7.0).animate(
47 | CurvedAnimation(
48 | parent: _controller,
49 | curve: const Interval(0.0, 1.0, curve: Curves.easeOut),
50 | ),
51 | );
52 | }
53 |
54 | @override
55 | void dispose() {
56 | if (widget.controller == null) {
57 | _controller.dispose();
58 | }
59 | super.dispose();
60 | }
61 |
62 | @override
63 | Widget build(BuildContext context) {
64 | return Center(
65 | child: Transform(
66 | transform: Matrix4.identity()..rotateY((0 - _animation.value) * pi),
67 | alignment: FractionalOffset.center,
68 | child: SizedBox.fromSize(
69 | size: Size.square(widget.size),
70 | child: _itemBuilder(0),
71 | ),
72 | ),
73 | );
74 | }
75 |
76 | Widget _itemBuilder(int index) => widget.itemBuilder != null
77 | ? widget.itemBuilder!(context, index)
78 | : DecoratedBox(
79 | decoration: BoxDecoration(color: widget.color, shape: widget.shape),
80 | );
81 | }
82 |
--------------------------------------------------------------------------------
/lib/src/square_circle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math;
2 |
3 | import 'package:flutter/widgets.dart';
4 |
5 | class SpinKitSquareCircle extends StatefulWidget {
6 | const SpinKitSquareCircle({
7 | Key? key,
8 | this.color,
9 | this.size = 50.0,
10 | this.itemBuilder,
11 | this.duration = const Duration(milliseconds: 500),
12 | this.controller,
13 | }) : assert(
14 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
15 | 'You should specify either a itemBuilder or a color',
16 | ),
17 | super(key: key);
18 |
19 | final Color? color;
20 | final double size;
21 | final IndexedWidgetBuilder? itemBuilder;
22 | final Duration duration;
23 | final AnimationController? controller;
24 |
25 | @override
26 | State createState() => _SpinKitSquareCircleState();
27 | }
28 |
29 | class _SpinKitSquareCircleState extends State with SingleTickerProviderStateMixin {
30 | late AnimationController _controller;
31 | late Animation _animationCurve;
32 | late Animation _animationSize;
33 |
34 | @override
35 | void initState() {
36 | super.initState();
37 |
38 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
39 | ..addListener(() {
40 | if (mounted) {
41 | setState(() {});
42 | }
43 | })
44 | ..repeat(reverse: true);
45 | final animation = CurvedAnimation(
46 | parent: _controller,
47 | curve: Curves.easeInOutCubic,
48 | );
49 | _animationCurve = Tween(begin: 1.0, end: 0.0).animate(animation);
50 | _animationSize = Tween(begin: 0.5, end: 1.0).animate(animation);
51 | }
52 |
53 | @override
54 | void dispose() {
55 | if (widget.controller == null) {
56 | _controller.dispose();
57 | }
58 | super.dispose();
59 | }
60 |
61 | @override
62 | Widget build(BuildContext context) {
63 | final sizeValue = widget.size * _animationSize.value;
64 | return Center(
65 | child: Transform(
66 | transform: Matrix4.identity()..rotateZ(_animationCurve.value * math.pi),
67 | alignment: FractionalOffset.center,
68 | child: SizedBox.fromSize(
69 | size: Size.square(sizeValue),
70 | child: _itemBuilder(0, 0.5 * sizeValue * _animationCurve.value),
71 | ),
72 | ),
73 | );
74 | }
75 |
76 | Widget _itemBuilder(int index, double curveValue) {
77 | return widget.itemBuilder != null
78 | ? widget.itemBuilder!(context, index)
79 | : DecoratedBox(
80 | decoration: BoxDecoration(
81 | color: widget.color,
82 | borderRadius: BorderRadius.all(Radius.circular(curveValue)),
83 | ),
84 | );
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/lib/src/three_bounce.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_spinkit/src/tweens/delay_tween.dart';
3 |
4 | class SpinKitThreeBounce extends StatefulWidget {
5 | const SpinKitThreeBounce({
6 | Key? key,
7 | this.color,
8 | this.size = 50.0,
9 | this.itemBuilder,
10 | this.duration = const Duration(milliseconds: 1400),
11 | this.controller,
12 | }) : assert(
13 | !(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
14 | 'You should specify either a itemBuilder or a color',
15 | ),
16 | super(key: key);
17 |
18 | final Color? color;
19 | final double size;
20 | final IndexedWidgetBuilder? itemBuilder;
21 | final Duration duration;
22 | final AnimationController? controller;
23 |
24 | @override
25 | State createState() => _SpinKitThreeBounceState();
26 | }
27 |
28 | class _SpinKitThreeBounceState extends State with SingleTickerProviderStateMixin {
29 | late AnimationController _controller;
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 |
35 | _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
36 | }
37 |
38 | @override
39 | void dispose() {
40 | if (widget.controller == null) {
41 | _controller.dispose();
42 | }
43 | super.dispose();
44 | }
45 |
46 | @override
47 | Widget build(BuildContext context) {
48 | return Center(
49 | child: SizedBox.fromSize(
50 | size: Size(widget.size * 2, widget.size),
51 | child: Row(
52 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
53 | children: List.generate(3, (i) {
54 | return ScaleTransition(
55 | scale: DelayTween(
56 | begin: 0.0,
57 | end: 1.0,
58 | delay: i * .2,
59 | ).animate(_controller),
60 | child: SizedBox.fromSize(
61 | size: Size.square(widget.size * 0.5),
62 | child: _itemBuilder(i),
63 | ),
64 | );
65 | }),
66 | ),
67 | ),
68 | );
69 | }
70 |
71 | Widget _itemBuilder(int index) => widget.itemBuilder != null
72 | ? widget.itemBuilder!(context, index)
73 | : DecoratedBox(
74 | decoration: BoxDecoration(
75 | color: widget.color,
76 | shape: BoxShape.circle,
77 | ),
78 | );
79 | }
80 |
--------------------------------------------------------------------------------
/lib/src/tweens/delay_tween.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math show sin, pi;
2 |
3 | import 'package:flutter/animation.dart';
4 |
5 | class DelayTween extends Tween {
6 | DelayTween({
7 | double? begin,
8 | double? end,
9 | required this.delay,
10 | }) : super(begin: begin, end: end);
11 |
12 | final double delay;
13 |
14 | @override
15 | double lerp(double t) {
16 | return super.lerp((math.sin((t - delay) * 2 * math.pi) + 1) / 2);
17 | }
18 |
19 | @override
20 | double evaluate(Animation animation) => lerp(animation.value);
21 | }
22 |
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 | test_coverage:
2 | flutter test --no-pub --coverage
3 |
4 | build_coverage:
5 | make test_coverage && genhtml -o coverage coverage/lcov.info
6 |
7 | open_coverage:
8 | make build_coverage && open coverage/index.html
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_spinkit
2 | description: A collection of loading indicators animated with flutter. Heavily inspired by @tobiasahlin's SpinKit.
3 | version: 5.2.1
4 | homepage: https://github.com/jogboms/flutter_spinkit
5 |
6 | environment:
7 | sdk: '>=2.12.0 <3.0.0'
8 | flutter: ">=2.0.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 |
14 | dev_dependencies:
15 | flutter_test:
16 | sdk: flutter
17 | flutter_lints: ^2.0.1
18 |
--------------------------------------------------------------------------------
/screenshots/FadingCube.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/FadingCube.gif
--------------------------------------------------------------------------------
/screenshots/FadingFour.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/FadingFour.gif
--------------------------------------------------------------------------------
/screenshots/PouringHourGlass.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/PouringHourGlass.gif
--------------------------------------------------------------------------------
/screenshots/dancing-square.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/dancing-square.gif
--------------------------------------------------------------------------------
/screenshots/dual-ring.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/dual-ring.gif
--------------------------------------------------------------------------------
/screenshots/grid.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/grid.gif
--------------------------------------------------------------------------------
/screenshots/heart.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/heart.gif
--------------------------------------------------------------------------------
/screenshots/hour-glass.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/hour-glass.gif
--------------------------------------------------------------------------------
/screenshots/itemBuilder.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/itemBuilder.gif
--------------------------------------------------------------------------------
/screenshots/piano-wave.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/piano-wave.gif
--------------------------------------------------------------------------------
/screenshots/pouring-hour-glass-refined.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/pouring-hour-glass-refined.gif
--------------------------------------------------------------------------------
/screenshots/pulsing-grid.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/pulsing-grid.gif
--------------------------------------------------------------------------------
/screenshots/ring.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/ring.gif
--------------------------------------------------------------------------------
/screenshots/ripple.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/ripple.gif
--------------------------------------------------------------------------------
/screenshots/spinkit_wave_spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/spinkit_wave_spinner.gif
--------------------------------------------------------------------------------
/screenshots/spinning-circle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/spinning-circle.gif
--------------------------------------------------------------------------------
/screenshots/spinning-lines.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/spinning-lines.gif
--------------------------------------------------------------------------------
/screenshots/square_circle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/square_circle.gif
--------------------------------------------------------------------------------
/screenshots/three-in-out.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jogboms/flutter_spinkit/360fa803d6888675a89b3cb44f25d99168eee351/screenshots/three-in-out.gif
--------------------------------------------------------------------------------
/test/chasing_dots_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('ChasingDots', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitChasingDots(), throwsAssertionError);
13 | expect(
14 | () => SpinKitChasingDots(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitChasingDots(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitChasingDots(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitChasingDots(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitChasingDots), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitChasingDots(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitChasingDots), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitChasingDots(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitChasingDots), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/circle_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('Circle', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitCircle(), throwsAssertionError);
13 | expect(
14 | () => SpinKitCircle(color: Colors.white, itemBuilder: fakeBoxBuilder),
15 | throwsAssertionError,
16 | );
17 | },
18 | );
19 |
20 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
21 | expect(() => SpinKitCircle(color: null), throwsAssertionError);
22 | });
23 |
24 | testWidgets(
25 | 'needs itemBuilder to be non-null',
26 | (WidgetTester tester) async {
27 | expect(() => SpinKitCircle(itemBuilder: null), throwsAssertionError);
28 | },
29 | );
30 |
31 | testWidgets('works with color', (WidgetTester tester) async {
32 | await tester.pumpWidget(
33 | createMaterialApp(const SpinKitCircle(color: Colors.white)),
34 | );
35 | expect(find.byType(SpinKitCircle), findsOneWidget);
36 | expect(find.byType(DecoratedBox), findsWidgets);
37 | tester.verifyTickersWereDisposed();
38 | });
39 |
40 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
41 | await tester.pumpWidget(
42 | createMaterialApp(const SpinKitCircle(itemBuilder: fakeBoxBuilder)),
43 | );
44 | expect(find.byType(SpinKitCircle), findsOneWidget);
45 | expect(find.byType(FakeBox), findsWidgets);
46 | tester.verifyTickersWereDisposed();
47 | });
48 |
49 | testWidgets('works without Material', (WidgetTester tester) async {
50 | await tester.pumpWidget(
51 | createWidgetsApp(const SpinKitCircle(color: Colors.white)),
52 | );
53 | expect(find.byType(SpinKitCircle), findsOneWidget);
54 | expect(find.byType(DecoratedBox), findsWidgets);
55 | tester.verifyTickersWereDisposed();
56 | });
57 | });
58 | }
59 |
--------------------------------------------------------------------------------
/test/cube_grid_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('CubeGrid', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitCubeGrid(), throwsAssertionError);
13 | expect(
14 | () =>
15 | SpinKitCubeGrid(color: Colors.white, itemBuilder: fakeBoxBuilder),
16 | throwsAssertionError,
17 | );
18 | },
19 | );
20 |
21 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
22 | expect(() => SpinKitCubeGrid(color: null), throwsAssertionError);
23 | });
24 |
25 | testWidgets(
26 | 'needs itemBuilder to be non-null',
27 | (WidgetTester tester) async {
28 | expect(() => SpinKitCubeGrid(itemBuilder: null), throwsAssertionError);
29 | },
30 | );
31 |
32 | testWidgets('works with color', (WidgetTester tester) async {
33 | await tester.pumpWidget(
34 | createMaterialApp(const SpinKitCubeGrid(color: Colors.white)),
35 | );
36 | expect(find.byType(SpinKitCubeGrid), findsOneWidget);
37 | expect(find.byType(DecoratedBox), findsWidgets);
38 | tester.verifyTickersWereDisposed();
39 | });
40 |
41 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
42 | await tester.pumpWidget(
43 | createMaterialApp(
44 | const SpinKitCubeGrid(itemBuilder: fakeBoxBuilder),
45 | ),
46 | );
47 | expect(find.byType(SpinKitCubeGrid), findsOneWidget);
48 | expect(find.byType(FakeBox), findsWidgets);
49 | tester.verifyTickersWereDisposed();
50 | });
51 |
52 | testWidgets('works without Material', (WidgetTester tester) async {
53 | await tester.pumpWidget(
54 | createWidgetsApp(const SpinKitCubeGrid(color: Colors.white)),
55 | );
56 | expect(find.byType(SpinKitCubeGrid), findsOneWidget);
57 | expect(find.byType(DecoratedBox), findsWidgets);
58 | tester.verifyTickersWereDisposed();
59 | });
60 | });
61 | }
62 |
--------------------------------------------------------------------------------
/test/dancing_square_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('DancingSquare', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitDancingSquare(), throwsAssertionError);
13 | expect(
14 | () => SpinKitDancingSquare(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitDancingSquare(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitDancingSquare(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitDancingSquare(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitDancingSquare), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitDancingSquare(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitDancingSquare), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitDancingSquare(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitDancingSquare), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/double_bounce_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('DoubleBounce', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitDoubleBounce(), throwsAssertionError);
13 | expect(
14 | () => SpinKitDoubleBounce(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitDoubleBounce(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitDoubleBounce(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitDoubleBounce(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitDoubleBounce), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitDoubleBounce(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitDoubleBounce), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitDoubleBounce(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitDoubleBounce), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/dual_ring_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('DualRing', () {
9 | testWidgets('works with color', (WidgetTester tester) async {
10 | await tester.pumpWidget(
11 | createMaterialApp(const SpinKitDualRing(color: Colors.white)),
12 | );
13 | expect(find.byType(SpinKitDualRing), findsOneWidget);
14 | expect(find.byType(CustomPaint), findsWidgets);
15 | tester.verifyTickersWereDisposed();
16 | });
17 |
18 | testWidgets('works without Material', (WidgetTester tester) async {
19 | await tester.pumpWidget(
20 | createWidgetsApp(const SpinKitDualRing(color: Colors.white)),
21 | );
22 | expect(find.byType(SpinKitDualRing), findsOneWidget);
23 | expect(find.byType(CustomPaint), findsWidgets);
24 | tester.verifyTickersWereDisposed();
25 | });
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/test/fading_circle_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('FadingCircle', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitFadingCircle(), throwsAssertionError);
13 | expect(
14 | () => SpinKitFadingCircle(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitFadingCircle(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitFadingCircle(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitFadingCircle(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitFadingCircle), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitFadingCircle(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitFadingCircle), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitFadingCircle(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitFadingCircle), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/fading_cube_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('FadingCube', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitFadingCube(), throwsAssertionError);
13 | expect(
14 | () => SpinKitFadingCube(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitFadingCube(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitFadingCube(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitFadingCube(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitFadingCube), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitFadingCube(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitFadingCube), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitFadingCube(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitFadingCube), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/fading_four_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('FadingFour', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitFadingFour(), throwsAssertionError);
13 | expect(
14 | () => SpinKitFadingFour(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitFadingFour(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitFadingFour(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitFadingFour(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitFadingFour), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitFadingFour(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitFadingFour), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitFadingFour(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitFadingFour), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/fading_grid_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('FadingGrid', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitFadingGrid(), throwsAssertionError);
13 | expect(
14 | () => SpinKitFadingGrid(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitFadingGrid(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitFadingGrid(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitFadingGrid(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitFadingGrid), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitFadingGrid(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitFadingGrid), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitFadingGrid(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitFadingGrid), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/folding_cube_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('FoldingCube', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitFoldingCube(), throwsAssertionError);
13 | expect(
14 | () => SpinKitFoldingCube(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitFoldingCube(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitFoldingCube(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitFoldingCube(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitFoldingCube), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitFoldingCube(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitFoldingCube), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitFoldingCube(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitFoldingCube), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/helpers.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class FakeBox extends SizedBox {
4 | const FakeBox({Key? key}) : super(key: key);
5 | }
6 |
7 | Widget fakeBoxBuilder(BuildContext _, int index) => const FakeBox();
8 |
9 | Widget createWidgetsApp(Widget widget) {
10 | return WidgetsApp(
11 | color: Colors.grey[900]!,
12 | home: Center(child: widget),
13 | pageRouteBuilder: (settings, builder) => MaterialPageRoute(
14 | settings: settings,
15 | builder: builder,
16 | ),
17 | );
18 | }
19 |
20 | Widget createMaterialApp(Widget widget) {
21 | return MaterialApp(theme: ThemeData.dark(), home: Center(child: widget));
22 | }
23 |
--------------------------------------------------------------------------------
/test/hour_glass_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('HourGlass', () {
9 | testWidgets('works with color', (WidgetTester tester) async {
10 | await tester.pumpWidget(
11 | createMaterialApp(const SpinKitHourGlass(color: Colors.white)),
12 | );
13 | expect(find.byType(SpinKitHourGlass), findsOneWidget);
14 | expect(find.byType(CustomPaint), findsWidgets);
15 | tester.verifyTickersWereDisposed();
16 | });
17 |
18 | testWidgets('works without Material', (WidgetTester tester) async {
19 | await tester.pumpWidget(
20 | createWidgetsApp(const SpinKitHourGlass(color: Colors.white)),
21 | );
22 | expect(find.byType(SpinKitHourGlass), findsOneWidget);
23 | expect(find.byType(CustomPaint), findsWidgets);
24 | tester.verifyTickersWereDisposed();
25 | });
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/test/piano_wave_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('PianoWave', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitPianoWave(), throwsAssertionError);
13 | expect(
14 | () => SpinKitPianoWave(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitPianoWave(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(() => SpinKitPianoWave(itemBuilder: null), throwsAssertionError);
31 | },
32 | );
33 |
34 | group('works with types', () {
35 | testWidgets('works with types', (WidgetTester tester) async {
36 | await tester.pumpWidget(
37 | createMaterialApp(
38 | const SpinKitPianoWave(
39 | color: Colors.white,
40 | type: SpinKitPianoWaveType.start,
41 | ),
42 | ),
43 | );
44 | expect(find.byType(SpinKitPianoWave), findsOneWidget);
45 | expect(find.byType(DecoratedBox), findsWidgets);
46 | tester.verifyTickersWereDisposed();
47 | });
48 |
49 | testWidgets('works with types', (WidgetTester tester) async {
50 | await tester.pumpWidget(
51 | createMaterialApp(
52 | const SpinKitPianoWave(
53 | color: Colors.white,
54 | type: SpinKitPianoWaveType.center,
55 | ),
56 | ),
57 | );
58 | expect(find.byType(SpinKitPianoWave), findsOneWidget);
59 | expect(find.byType(DecoratedBox), findsWidgets);
60 | tester.verifyTickersWereDisposed();
61 | });
62 |
63 | testWidgets('works with types', (WidgetTester tester) async {
64 | await tester.pumpWidget(
65 | createMaterialApp(
66 | const SpinKitPianoWave(
67 | color: Colors.white,
68 | type: SpinKitPianoWaveType.end,
69 | ),
70 | ),
71 | );
72 | expect(find.byType(SpinKitPianoWave), findsOneWidget);
73 | expect(find.byType(DecoratedBox), findsWidgets);
74 | tester.verifyTickersWereDisposed();
75 | });
76 | });
77 |
78 | testWidgets('works with color', (WidgetTester tester) async {
79 | await tester.pumpWidget(
80 | createMaterialApp(const SpinKitPianoWave(color: Colors.white)),
81 | );
82 | expect(find.byType(SpinKitPianoWave), findsOneWidget);
83 | expect(find.byType(DecoratedBox), findsWidgets);
84 | tester.verifyTickersWereDisposed();
85 | });
86 |
87 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
88 | await tester.pumpWidget(
89 | createMaterialApp(
90 | const SpinKitPianoWave(itemBuilder: fakeBoxBuilder),
91 | ),
92 | );
93 | expect(find.byType(SpinKitPianoWave), findsOneWidget);
94 | expect(find.byType(FakeBox), findsWidgets);
95 | tester.verifyTickersWereDisposed();
96 | });
97 |
98 | testWidgets('works without Material', (WidgetTester tester) async {
99 | await tester.pumpWidget(
100 | createWidgetsApp(const SpinKitPianoWave(color: Colors.white)),
101 | );
102 | expect(find.byType(SpinKitPianoWave), findsOneWidget);
103 | expect(find.byType(DecoratedBox), findsWidgets);
104 | tester.verifyTickersWereDisposed();
105 | });
106 | });
107 | }
108 |
--------------------------------------------------------------------------------
/test/pouring_hour_glass_refined_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('PouringHourGlassRefined', () {
9 | testWidgets('works with color', (WidgetTester tester) async {
10 | await tester.pumpWidget(
11 | createMaterialApp(
12 | const SpinKitPouringHourGlassRefined(color: Colors.white),
13 | ),
14 | );
15 | expect(find.byType(SpinKitPouringHourGlassRefined), findsOneWidget);
16 | expect(find.byType(CustomPaint), findsWidgets);
17 | tester.verifyTickersWereDisposed();
18 | });
19 |
20 | testWidgets('works without Material', (WidgetTester tester) async {
21 | await tester.pumpWidget(
22 | createWidgetsApp(
23 | const SpinKitPouringHourGlassRefined(color: Colors.white),
24 | ),
25 | );
26 | expect(find.byType(SpinKitPouringHourGlassRefined), findsOneWidget);
27 | expect(find.byType(CustomPaint), findsWidgets);
28 | tester.verifyTickersWereDisposed();
29 | });
30 | });
31 | }
32 |
--------------------------------------------------------------------------------
/test/pouring_hour_glass_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('PouringHourglass', () {
9 | testWidgets('works with color', (WidgetTester tester) async {
10 | await tester.pumpWidget(
11 | createMaterialApp(
12 | const SpinKitPouringHourGlass(color: Colors.white),
13 | ),
14 | );
15 | expect(find.byType(SpinKitPouringHourGlass), findsOneWidget);
16 | expect(find.byType(CustomPaint), findsWidgets);
17 | tester.verifyTickersWereDisposed();
18 | });
19 |
20 | testWidgets('works without Material', (WidgetTester tester) async {
21 | await tester.pumpWidget(
22 | createWidgetsApp(const SpinKitPouringHourGlass(color: Colors.white)),
23 | );
24 | expect(find.byType(SpinKitPouringHourGlass), findsOneWidget);
25 | expect(find.byType(CustomPaint), findsWidgets);
26 | tester.verifyTickersWereDisposed();
27 | });
28 | });
29 | }
30 |
--------------------------------------------------------------------------------
/test/pulse_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('Pulse', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitPulse(), throwsAssertionError);
13 | expect(
14 | () => SpinKitPulse(color: Colors.white, itemBuilder: fakeBoxBuilder),
15 | throwsAssertionError,
16 | );
17 | },
18 | );
19 |
20 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
21 | expect(() => SpinKitPulse(color: null), throwsAssertionError);
22 | });
23 |
24 | testWidgets(
25 | 'needs itemBuilder to be non-null',
26 | (WidgetTester tester) async {
27 | expect(() => SpinKitPulse(itemBuilder: null), throwsAssertionError);
28 | },
29 | );
30 |
31 | testWidgets('works with color', (WidgetTester tester) async {
32 | await tester.pumpWidget(
33 | createMaterialApp(const SpinKitPulse(color: Colors.white)),
34 | );
35 | expect(find.byType(SpinKitPulse), findsOneWidget);
36 | expect(find.byType(DecoratedBox), findsWidgets);
37 | tester.verifyTickersWereDisposed();
38 | });
39 |
40 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
41 | await tester.pumpWidget(
42 | createMaterialApp(const SpinKitPulse(itemBuilder: fakeBoxBuilder)),
43 | );
44 | expect(find.byType(SpinKitPulse), findsOneWidget);
45 | expect(find.byType(FakeBox), findsWidgets);
46 | tester.verifyTickersWereDisposed();
47 | });
48 |
49 | testWidgets('works without Material', (WidgetTester tester) async {
50 | await tester.pumpWidget(
51 | createWidgetsApp(const SpinKitPulse(color: Colors.white)),
52 | );
53 | expect(find.byType(SpinKitPulse), findsOneWidget);
54 | expect(find.byType(DecoratedBox), findsWidgets);
55 | tester.verifyTickersWereDisposed();
56 | });
57 | });
58 | }
59 |
--------------------------------------------------------------------------------
/test/pulsing_grid_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('PulsingGrid', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitPulsingGrid(), throwsAssertionError);
13 | expect(
14 | () => SpinKitPulsingGrid(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitPulsingGrid(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitPulsingGrid(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitPulsingGrid(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitPulsingGrid), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitPulsingGrid(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitPulsingGrid), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitPulsingGrid(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitPulsingGrid), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/pumping_heart_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_spinkit/flutter_spinkit.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 |
6 | import 'helpers.dart';
7 |
8 | void main() {
9 | group('PumpingHeart', () {
10 | testWidgets(
11 | 'needs either color or itemBuilder',
12 | (WidgetTester tester) async {
13 | expect(() => SpinKitPumpingHeart(), throwsAssertionError);
14 | expect(
15 | () => SpinKitPumpingHeart(
16 | color: Colors.white,
17 | itemBuilder: fakeBoxBuilder,
18 | ),
19 | throwsAssertionError,
20 | );
21 | },
22 | );
23 |
24 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
25 | expect(() => SpinKitPumpingHeart(color: null), throwsAssertionError);
26 | });
27 |
28 | testWidgets(
29 | 'needs itemBuilder to be non-null',
30 | (WidgetTester tester) async {
31 | expect(
32 | () => SpinKitPumpingHeart(itemBuilder: null),
33 | throwsAssertionError,
34 | );
35 | },
36 | );
37 |
38 | testWidgets('works with color', (WidgetTester tester) async {
39 | await tester.pumpWidget(
40 | createMaterialApp(const SpinKitPumpingHeart(color: Colors.white)),
41 | );
42 | expect(find.byType(SpinKitPumpingHeart), findsOneWidget);
43 | expect(find.byType(Icon), findsWidgets);
44 | tester.verifyTickersWereDisposed();
45 | });
46 |
47 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
48 | await tester.pumpWidget(
49 | createMaterialApp(
50 | const SpinKitPumpingHeart(itemBuilder: fakeBoxBuilder),
51 | ),
52 | );
53 | expect(find.byType(SpinKitPumpingHeart), findsOneWidget);
54 | expect(find.byType(FakeBox), findsWidgets);
55 | tester.verifyTickersWereDisposed();
56 | });
57 |
58 | testWidgets('works without Material', (WidgetTester tester) async {
59 | await tester.pumpWidget(
60 | createWidgetsApp(const SpinKitPumpingHeart(color: Colors.white)),
61 | );
62 | expect(find.byType(SpinKitPumpingHeart), findsOneWidget);
63 | expect(find.byType(Icon), findsWidgets);
64 | tester.verifyTickersWereDisposed();
65 | });
66 |
67 | test('on curve', () {
68 | // I really don't know how else to test this. Too many magic numbers
69 | const anotherMagicNumber = .8636363638;
70 | const curve = SpinKitPumpCurve();
71 | expect(curve.transform(0), 0);
72 | expect(
73 | curve.transform(.25),
74 | closeTo(anotherMagicNumber, precisionErrorTolerance),
75 | );
76 | expect(curve.transform(.5), 0);
77 | expect(
78 | curve.transform(.75),
79 | closeTo(anotherMagicNumber / 2, precisionErrorTolerance),
80 | );
81 | expect(curve.transform(1), 0);
82 | });
83 | });
84 | }
85 |
--------------------------------------------------------------------------------
/test/ring_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_spinkit/flutter_spinkit.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 |
6 | import 'helpers.dart';
7 |
8 | void main() {
9 | group('Ring', () {
10 | testWidgets('works with color', (WidgetTester tester) async {
11 | await tester.pumpWidget(
12 | createMaterialApp(const SpinKitRing(color: Colors.white)),
13 | );
14 | expect(find.byType(SpinKitRing), findsOneWidget);
15 | expect(find.byType(CustomPaint), findsWidgets);
16 | tester.verifyTickersWereDisposed();
17 | });
18 |
19 | testWidgets('works without Material', (WidgetTester tester) async {
20 | await tester.pumpWidget(
21 | createWidgetsApp(const SpinKitRing(color: Colors.white)),
22 | );
23 | expect(find.byType(SpinKitRing), findsOneWidget);
24 | expect(find.byType(CustomPaint), findsWidgets);
25 | tester.verifyTickersWereDisposed();
26 | });
27 |
28 | test('on curve', () {
29 | const curve = SpinKitRingCurve();
30 | expect(curve.transform(1), 0);
31 | expect(curve.transform(.9), closeTo(.2, precisionErrorTolerance));
32 | expect(curve.transform(.5), 1);
33 | expect(curve.transform(.1), closeTo(.2, precisionErrorTolerance));
34 | expect(curve.transform(0), 0);
35 | });
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/test/ripple_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('Ripple', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitRipple(), throwsAssertionError);
13 | expect(
14 | () => SpinKitRipple(color: Colors.white, itemBuilder: fakeBoxBuilder),
15 | throwsAssertionError,
16 | );
17 | },
18 | );
19 |
20 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
21 | expect(() => SpinKitRipple(color: null), throwsAssertionError);
22 | });
23 |
24 | testWidgets(
25 | 'needs itemBuilder to be non-null',
26 | (WidgetTester tester) async {
27 | expect(() => SpinKitRipple(itemBuilder: null), throwsAssertionError);
28 | },
29 | );
30 |
31 | testWidgets('works with color', (WidgetTester tester) async {
32 | await tester.pumpWidget(
33 | createMaterialApp(const SpinKitRipple(color: Colors.white)),
34 | );
35 | expect(find.byType(SpinKitRipple), findsOneWidget);
36 | expect(find.byType(DecoratedBox), findsWidgets);
37 | tester.verifyTickersWereDisposed();
38 | });
39 |
40 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
41 | await tester.pumpWidget(
42 | createMaterialApp(const SpinKitRipple(itemBuilder: fakeBoxBuilder)),
43 | );
44 | expect(find.byType(SpinKitRipple), findsOneWidget);
45 | expect(find.byType(FakeBox), findsWidgets);
46 | tester.verifyTickersWereDisposed();
47 | });
48 |
49 | testWidgets('works without Material', (WidgetTester tester) async {
50 | await tester.pumpWidget(
51 | createWidgetsApp(const SpinKitRipple(color: Colors.white)),
52 | );
53 | expect(find.byType(SpinKitRipple), findsOneWidget);
54 | expect(find.byType(DecoratedBox), findsWidgets);
55 | tester.verifyTickersWereDisposed();
56 | });
57 | });
58 | }
59 |
--------------------------------------------------------------------------------
/test/rotating_circle_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('RotatingCircle', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitRotatingCircle(), throwsAssertionError);
13 | expect(
14 | () => SpinKitRotatingCircle(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitRotatingCircle(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitRotatingCircle(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitRotatingCircle(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitRotatingCircle), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitRotatingCircle(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitRotatingCircle), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitRotatingCircle(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitRotatingCircle), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/rotating_plain_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('RotatingPlain', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitRotatingPlain(), throwsAssertionError);
13 | expect(
14 | () => SpinKitRotatingPlain(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitRotatingPlain(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitRotatingPlain(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitRotatingPlain(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitRotatingPlain), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitRotatingPlain(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitRotatingPlain), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitRotatingPlain(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitRotatingPlain), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/smoke_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | void main() {
6 | testWidgets('Smoke test', (WidgetTester tester) async {
7 | await tester.pumpWidget(
8 | MaterialApp(
9 | theme: ThemeData.dark(),
10 | home: const SingleChildScrollView(
11 | child: Column(
12 | children: [
13 | SpinKitChasingDots(color: Colors.white),
14 | SpinKitCircle(color: Colors.white),
15 | SpinKitSquareCircle(color: Colors.white),
16 | SpinKitDoubleBounce(color: Colors.white),
17 | SpinKitCubeGrid(color: Colors.white),
18 | SpinKitDoubleBounce(color: Colors.white),
19 | SpinKitDualRing(color: Colors.white),
20 | SpinKitFadingCircle(color: Colors.white),
21 | SpinKitFadingCube(color: Colors.white),
22 | SpinKitFadingFour(color: Colors.white),
23 | SpinKitFadingGrid(color: Colors.white),
24 | SpinKitFoldingCube(color: Colors.white),
25 | SpinKitHourGlass(color: Colors.white),
26 | SpinKitPouringHourGlass(color: Colors.white),
27 | SpinKitPouringHourGlassRefined(color: Colors.white),
28 | SpinKitPulse(color: Colors.white),
29 | SpinKitPulsingGrid(color: Colors.white),
30 | SpinKitPumpingHeart(color: Colors.white),
31 | SpinKitRing(color: Colors.white),
32 | SpinKitRipple(color: Colors.white),
33 | SpinKitRotatingCircle(color: Colors.white),
34 | SpinKitRotatingPlain(color: Colors.white),
35 | SpinKitSpinningCircle(color: Colors.white),
36 | SpinKitSpinningLines(color: Colors.white),
37 | SpinKitThreeBounce(color: Colors.white),
38 | SpinKitThreeInOut(color: Colors.white),
39 | SpinKitWanderingCubes(color: Colors.white),
40 | SpinKitWave(color: Colors.white),
41 | SpinKitPianoWave(color: Colors.white),
42 | SpinKitDancingSquare(color: Colors.white),
43 | ],
44 | ),
45 | ),
46 | ),
47 | );
48 |
49 | await tester.pump();
50 | });
51 | }
52 |
--------------------------------------------------------------------------------
/test/spinning_circle_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('SpinningCircle', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitSpinningCircle(), throwsAssertionError);
13 | expect(
14 | () => SpinKitSpinningCircle(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitSpinningCircle(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitSpinningCircle(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitSpinningCircle(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitSpinningCircle), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitSpinningCircle(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitSpinningCircle), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitSpinningCircle(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitSpinningCircle), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/spinning_line_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('SpinningLines', () {
9 | testWidgets('works with color', (WidgetTester tester) async {
10 | await tester.pumpWidget(
11 | createMaterialApp(const SpinKitSpinningLines(color: Colors.white)),
12 | );
13 | expect(find.byType(SpinKitSpinningLines), findsOneWidget);
14 | expect(find.byType(CustomPaint), findsWidgets);
15 | tester.verifyTickersWereDisposed();
16 | });
17 |
18 | testWidgets('works without Material', (WidgetTester tester) async {
19 | await tester.pumpWidget(
20 | createWidgetsApp(const SpinKitSpinningLines(color: Colors.white)),
21 | );
22 | expect(find.byType(SpinKitSpinningLines), findsOneWidget);
23 | expect(find.byType(CustomPaint), findsWidgets);
24 | tester.verifyTickersWereDisposed();
25 | });
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/test/square_circle_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('SquareCircle', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitSquareCircle(), throwsAssertionError);
13 | expect(
14 | () => SpinKitSquareCircle(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitSquareCircle(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitSquareCircle(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitSquareCircle(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitSquareCircle), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitSquareCircle(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitSquareCircle), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitSquareCircle(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitSquareCircle), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/three_bounce_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('ThreeBounce', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitThreeBounce(), throwsAssertionError);
13 | expect(
14 | () => SpinKitThreeBounce(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitThreeBounce(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitThreeBounce(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitThreeBounce(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitThreeBounce), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitThreeBounce(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitThreeBounce), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitThreeBounce(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitThreeBounce), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/three_in_out_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('ThreeInOut', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitThreeInOut(), throwsAssertionError);
13 | expect(
14 | () => SpinKitThreeInOut(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitThreeInOut(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitThreeInOut(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitThreeInOut(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitThreeInOut), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitThreeInOut(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitThreeInOut), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitThreeInOut(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitThreeInOut), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/wandering_cubes_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('WanderingCubes', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitWanderingCubes(), throwsAssertionError);
13 | expect(
14 | () => SpinKitWanderingCubes(
15 | color: Colors.white,
16 | itemBuilder: fakeBoxBuilder,
17 | ),
18 | throwsAssertionError,
19 | );
20 | },
21 | );
22 |
23 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
24 | expect(() => SpinKitWanderingCubes(color: null), throwsAssertionError);
25 | });
26 |
27 | testWidgets(
28 | 'needs itemBuilder to be non-null',
29 | (WidgetTester tester) async {
30 | expect(
31 | () => SpinKitWanderingCubes(itemBuilder: null),
32 | throwsAssertionError,
33 | );
34 | },
35 | );
36 |
37 | testWidgets('works with color', (WidgetTester tester) async {
38 | await tester.pumpWidget(
39 | createMaterialApp(const SpinKitWanderingCubes(color: Colors.white)),
40 | );
41 | expect(find.byType(SpinKitWanderingCubes), findsOneWidget);
42 | expect(find.byType(DecoratedBox), findsWidgets);
43 | tester.verifyTickersWereDisposed();
44 | });
45 |
46 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
47 | await tester.pumpWidget(
48 | createMaterialApp(
49 | const SpinKitWanderingCubes(itemBuilder: fakeBoxBuilder),
50 | ),
51 | );
52 | expect(find.byType(SpinKitWanderingCubes), findsOneWidget);
53 | expect(find.byType(FakeBox), findsWidgets);
54 | tester.verifyTickersWereDisposed();
55 | });
56 |
57 | testWidgets('works without Material', (WidgetTester tester) async {
58 | await tester.pumpWidget(
59 | createWidgetsApp(const SpinKitWanderingCubes(color: Colors.white)),
60 | );
61 | expect(find.byType(SpinKitWanderingCubes), findsOneWidget);
62 | expect(find.byType(DecoratedBox), findsWidgets);
63 | tester.verifyTickersWereDisposed();
64 | });
65 | });
66 | }
67 |
--------------------------------------------------------------------------------
/test/wave_spinner_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('Test SpinKitWaveSpinner', () {
9 | testWidgets(
10 | 'Ensure widget works without Material',
11 | (WidgetTester tester) async {
12 | await tester.pumpWidget(
13 | createWidgetsApp(const SpinKitWaveSpinner(color: Colors.white)),
14 | );
15 | expect(find.byType(SpinKitWaveSpinner), findsOneWidget);
16 | expect(find.byType(CustomPaint), findsWidgets);
17 |
18 | tester.verifyTickersWereDisposed();
19 | },
20 | );
21 |
22 | testWidgets(
23 | 'Ensure Icon is found when SpinKinWaveSpinner has a child of Icon',
24 | (WidgetTester tester) async {
25 | await tester.pumpWidget(
26 | createWidgetsApp(
27 | const SpinKitWaveSpinner(
28 | color: Colors.white,
29 | child: Icon(Icons.flutter_dash, size: 18),
30 | ),
31 | ),
32 | );
33 | expect(find.byType(Icon), findsOneWidget);
34 |
35 | tester.verifyTickersWereDisposed();
36 | },
37 | );
38 |
39 | testWidgets(
40 | 'Ensure that CustomPaint with SpinkitWaveCustomPaint painter exist',
41 | (WidgetTester tester) async {
42 | await tester.pumpWidget(
43 | createWidgetsApp(const SpinKitWaveSpinner(color: Colors.white)),
44 | );
45 | expect(_findPainter(tester), isA());
46 |
47 | tester.verifyTickersWereDisposed();
48 | },
49 | );
50 |
51 | group('Test painter entities', () {
52 | testWidgets(
53 | 'Ensure that default paint entities are set correctly',
54 | (WidgetTester tester) async {
55 | await tester.pumpWidget(
56 | createWidgetsApp(const SpinKitWaveSpinner(color: Colors.white)),
57 | );
58 | tester.verifyTickersWereDisposed();
59 | },
60 | );
61 |
62 | testWidgets(
63 | 'Ensure that entities are set correctly',
64 | (WidgetTester tester) async {
65 | await tester.pumpWidget(
66 | createWidgetsApp(
67 | const SpinKitWaveSpinner(
68 | waveColor: Colors.red,
69 | trackColor: Colors.lightBlue,
70 | color: Colors.pink,
71 | size: 50,
72 | duration: Duration(seconds: 1),
73 | curve: Curves.bounceIn,
74 | ),
75 | ),
76 | );
77 |
78 | final painter = _findPainter(tester);
79 | expect(painter.waveColor, Colors.red);
80 | expect(painter.trackColor, Colors.lightBlue);
81 | expect(painter.color, Colors.pink);
82 |
83 | tester.verifyTickersWereDisposed();
84 | },
85 | );
86 | });
87 | });
88 | }
89 |
90 | SpinkitWaveCustomPaint _findPainter(WidgetTester tester) {
91 | return (tester.firstWidget(
92 | find.byWidgetPredicate(
93 | (widget) =>
94 | (widget is CustomPaint) && widget.painter is SpinkitWaveCustomPaint,
95 | ),
96 | ) as CustomPaint)
97 | .painter! as SpinkitWaveCustomPaint;
98 | }
99 |
--------------------------------------------------------------------------------
/test/wave_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_spinkit/flutter_spinkit.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | import 'helpers.dart';
6 |
7 | void main() {
8 | group('Wave', () {
9 | testWidgets(
10 | 'needs either color or itemBuilder',
11 | (WidgetTester tester) async {
12 | expect(() => SpinKitWave(), throwsAssertionError);
13 | expect(
14 | () => SpinKitWave(color: Colors.white, itemBuilder: fakeBoxBuilder),
15 | throwsAssertionError,
16 | );
17 | },
18 | );
19 |
20 | testWidgets('needs color to be non-null', (WidgetTester tester) async {
21 | expect(() => SpinKitWave(color: null), throwsAssertionError);
22 | });
23 |
24 | testWidgets(
25 | 'needs itemBuilder to be non-null',
26 | (WidgetTester tester) async {
27 | expect(() => SpinKitWave(itemBuilder: null), throwsAssertionError);
28 | },
29 | );
30 |
31 | testWidgets('works with color', (WidgetTester tester) async {
32 | await tester.pumpWidget(
33 | createMaterialApp(const SpinKitWave(color: Colors.white)),
34 | );
35 | expect(find.byType(SpinKitWave), findsOneWidget);
36 | expect(find.byType(DecoratedBox), findsWidgets);
37 | tester.verifyTickersWereDisposed();
38 | });
39 |
40 | testWidgets('works with itemBuilder', (WidgetTester tester) async {
41 | await tester.pumpWidget(
42 | createMaterialApp(const SpinKitWave(itemBuilder: fakeBoxBuilder)),
43 | );
44 | expect(find.byType(SpinKitWave), findsOneWidget);
45 | expect(find.byType(FakeBox), findsWidgets);
46 | tester.verifyTickersWereDisposed();
47 | });
48 |
49 | group('works with types', () {
50 | testWidgets('on center', (WidgetTester tester) async {
51 | await tester.pumpWidget(
52 | createMaterialApp(
53 | const SpinKitWave(
54 | color: Colors.white,
55 | type: SpinKitWaveType.center,
56 | ),
57 | ),
58 | );
59 | expect(find.byType(SpinKitWave), findsOneWidget);
60 | expect(find.byType(DecoratedBox), findsWidgets);
61 | tester.verifyTickersWereDisposed();
62 | });
63 |
64 | testWidgets('on start', (WidgetTester tester) async {
65 | await tester.pumpWidget(
66 | createMaterialApp(
67 | const SpinKitWave(
68 | color: Colors.white,
69 | type: SpinKitWaveType.start,
70 | ),
71 | ),
72 | );
73 | expect(find.byType(SpinKitWave), findsOneWidget);
74 | expect(find.byType(DecoratedBox), findsWidgets);
75 | tester.verifyTickersWereDisposed();
76 | });
77 |
78 | testWidgets('on end', (WidgetTester tester) async {
79 | await tester.pumpWidget(
80 | createMaterialApp(
81 | const SpinKitWave(color: Colors.white, type: SpinKitWaveType.end),
82 | ),
83 | );
84 | expect(find.byType(SpinKitWave), findsOneWidget);
85 | expect(find.byType(DecoratedBox), findsWidgets);
86 | tester.verifyTickersWereDisposed();
87 | });
88 | });
89 |
90 | testWidgets('works without Material', (WidgetTester tester) async {
91 | await tester.pumpWidget(
92 | createWidgetsApp(const SpinKitWave(color: Colors.white)),
93 | );
94 | expect(find.byType(SpinKitWave), findsOneWidget);
95 | expect(find.byType(DecoratedBox), findsWidgets);
96 | tester.verifyTickersWereDisposed();
97 | });
98 | });
99 | }
100 |
--------------------------------------------------------------------------------