├── .gitignore
├── .metadata
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── doc
├── example-looney-tunes.png
├── example-pulse-icon.png
├── example-splash.png
├── example-tunnel.png
├── flutter-demo.gif
├── pulsator-icon.gif
├── pulsator-looney-tunes.gif
├── pulsator-splash.gif
└── pulsator-tunnel.gif
├── example
├── .gitignore
├── .metadata
├── 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.properties
│ └── settings.gradle
├── assets
│ └── android_phone.png
├── 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
├── pubspec.lock
└── pubspec.yaml
├── lib
├── pulsator.dart
└── src
│ ├── pulsator.dart
│ ├── pulse_icon.dart
│ └── styles.dart
└── pubspec.yaml
/.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 | build/
30 |
--------------------------------------------------------------------------------
/.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: "db7ef5bf9f59442b0e200a90587e8fa5e0c6336a"
8 | channel: "stable"
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.0.0+2
2 |
3 | * Updated pubspec.yaml file
4 |
5 | ## 1.0.0+1
6 |
7 | * Updated supported platforms
8 |
9 | ## 1.0.0
10 |
11 | * Initial release
12 |
13 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | - Using welcoming and inclusive language
12 | - Being respectful of differing viewpoints and experiences
13 | - Gracefully accepting constructive criticism
14 | - Focusing on what is best for the community
15 | - Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | - Trolling, insulting/derogatory comments, and personal or political attacks
21 | - Public or private harassment
22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | - Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, issues, and other contributions that are not aligned with this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html).
44 |
45 | For answers to common questions about this code of conduct, see [FAQ](https://www.contributor-covenant.org/faq).
46 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Pulsator
2 |
3 | Thank you for considering contributing to this open-source project! We welcome your contributions to make this library even better. Whether you want to report a bug, suggest an enhancement, or submit code changes, this guide will help you get started.
4 |
5 | Please note that this project follows a Code of Conduct (see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)). By participating, you are expected to uphold this code.
6 |
7 | ## Ways to Contribute
8 |
9 | You can contribute to this project in several ways:
10 |
11 | 1. Reporting Issues:
12 | - If you encounter a bug or have a feature request, please open an issue on the GitHub repository. Make sure to provide a clear and detailed description of the problem or feature request.
13 |
14 | 2. Code Contributions:
15 | - Fork the repository and make your changes in a feature branch.
16 | - Ensure your code follows the project's coding standards.
17 | - Write tests to cover your changes.
18 | - Submit a pull request with a clear description of your changes.
19 |
20 | 3. Documentation:
21 | - Help improve the project's documentation by correcting typos, enhancing explanations, or adding missing details.
22 |
23 | 4. Review Pull Requests:
24 | - Review open pull requests, provide feedback, and help ensure code quality.
25 |
26 | ## Getting Started
27 |
28 | 1. **Fork** the project repository to your GitHub account.
29 |
30 | 2. **Clone** your fork to your local development environment:
31 |
32 | ```bash
33 | git clone https://github.com/booncol/pulsator.git
34 | ```
35 | 3. **Create a branch** for your contribution:
36 |
37 | ```bash
38 | git checkout -b feature/my-feature
39 | ```
40 | 4. **Make your changes** and commit them:
41 |
42 | ```bash
43 | git add .
44 | git commit -m "Add new feature"
45 | ```
46 | 5. **Push** your changes to your GitHub repository:
47 |
48 | ```bash
49 | git push origin feature/my-feature
50 | ```
51 | 6. Open a **pull request** on the main repository for review.
52 |
53 | ## Code of Conduct
54 |
55 | This project has adopted a Code of Conduct that we expect project participants to adhere to. Please see [CODE_OF_CONDUCT.md](https://github.com/booncol/pulsator/blob/main/CODE_OF_CONDUCT.md) for details.
56 |
57 | ## License
58 |
59 | By contributing to this project, you agree that your contributions will be licensed under the MIT License. See the [LICENSE](https://github.com/booncol/pulsator/blob/main/LICENSE) for details.
60 |
61 | ## Contact
62 |
63 | If you have questions or need assistance, feel free to contact me.
64 |
65 | Happy coding!
66 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Lukasz Majda
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pulsator for Flutter
2 |
3 | [](https://pub.dev/packages/pulsator)
4 | 
5 |
6 | The Pulsator Flutter package brings a captivating pulsating animation to your Flutter applications.
7 |
8 | 
9 |
10 | ## Installation
11 |
12 | To integrate the Pulsator package into your Flutter project, add the following dependency to your `pubspec.yaml` file:
13 |
14 | ```yaml
15 | dependencies:
16 | pulsator: ^1.0.0
17 | ```
18 |
19 | After making the modification, run the following command in your terminal:
20 |
21 | ```bash
22 | flutter pub get
23 | ```
24 |
25 | ## Introduction
26 |
27 | The Pulsator package introduces two primary widgets: `Pulsator` and `PulseIcon`.
28 |
29 | ### `Pulsator` Widget
30 |
31 | The `Pulsator` widget allows you to create pulsating animations with customizable styles. You can control the number of pulses, animation duration, repetition, and more. This widget is perfect for adding dynamic visual effects to specific areas of your app.
32 |
33 | ```dart
34 | Pulsator(
35 | style: PulseStyle(color: Colors.blue),
36 | count: 5,
37 | duration: Duration(seconds: 4),
38 | repeat: 0,
39 | startFromScratch: false,
40 | autoStart: true,
41 | fit: PulseFit.contain,
42 | child: YourContentWidget(),
43 | )
44 | ```
45 |
46 | ### `PulseIcon` Widget
47 |
48 | The `PulseIcon` widget simplifies the process of displaying an icon with a pulsing effect. It allows you to customize the pulse and icon properties effortlessly.
49 |
50 | ```dart
51 | PulseIcon(
52 | icon: Icons.favorite,
53 | pulseColor: Colors.red,
54 | iconColor: Colors.white,
55 | iconSize: 44,
56 | innerSize: 54,
57 | pulseSize: 116,
58 | pulseCount: 4,
59 | pulseDuration: Duration(seconds: 4),
60 | )
61 | ```
62 |
63 | ## Features
64 |
65 | - **Customizable Styles**: Tailor the pulse animation to your preferences with adjustable color, size, and gradient configurations.
66 | - **Dynamic Pulse Effects**: Create dynamic and visually appealing pulsating animations that draw attention to specific elements in your UI.
67 | - **Icon Integration**: Easily incorporate pulsating effects into your icons using the `PulseIcon` widget for a more engaging user experience.
68 | - **Flexible Configuration**: Fine-tune the pulse behavior by adjusting parameters such as count, duration, repetition, and more.
69 |
70 | ## Usage
71 |
72 | Explore the various properties and customization options provided by the `Pulsator` and `PulseIcon` widgets to seamlessly integrate pulsating animations into your Flutter application. Experiment with different configurations to achieve the desired visual impact and enhance the overall user experience.
73 |
74 | ## Juicy examples
75 |
76 | | Code | Preview |
77 | |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
78 | |  |  |
79 | |  |  |
80 | |  |  |
81 | |  |  |
82 |
83 | ## License
84 | This project is licensed under the MIT License - see the [LICENSE](https://github.com/booncol/pulsator/blob/main/LICENSE) file for details.
85 |
86 | ## Contributing
87 | Please read [CONTRIBUTING.md](https://github.com/booncol/pulsator/blob/main/CONTRIBUTING.md) for details on my code of conduct, and the process for submitting pull requests to me.
88 |
89 | ## The docs, please!
90 |
91 | ### `Pulsator` Widget properties
92 |
93 | | Property | Type | Description |
94 | |--------------------|------------|-------------------------------------------------------------------------------------------------|
95 | | `style` | PulseStyle | Pulse style configuration. Required. |
96 | | `count` | int | Number of pulses visible at a time. Default is `3`. |
97 | | `duration` | Duration | Duration of a single pulse animation. Default is `2` seconds. |
98 | | `repeat` | int | Number of times pulses will repeat. If 0, pulses will repeat forever. Default is `0`. |
99 | | `startFromScratch` | bool | Whether the animation should start from the beginning. Default is `true`. |
100 | | `autoStart` | bool | Whether the animation should start automatically when the widget is created. Default is `true`. |
101 | | `fit` | PulseFit | How the pulse should be scaled to fit the widget size. Default is `PulseFit.contain`. |
102 | | `child` | Widget? | The child of the widget that is rendered on top of the pulses. Default is `null`. |
103 |
104 | #### `Events`
105 |
106 | | Event | Description |
107 | |----------|---------------------------------------------------|
108 | | `onCreated` | Invoked when the animation controller is created. |
109 | | `onCompleted` | Invoked when the animation is completed. |
110 |
111 |
112 | ### `PulseIcon` Widget properties
113 |
114 | | Property | Type | Description |
115 | |-----------------|----------|-------------------------------------------------------------------|
116 | | `icon` | IconData | The icon to display. Required. |
117 | | `pulseColor` | Color | The color of the pulse. Required. |
118 | | `iconColor` | Color | The color of the icon. Default is `white`. |
119 | | `iconSize` | double | The size of the icon. Default is `24`. |
120 | | `pulseSize` | double | The size of the pulse. Default is `64`. |
121 | | `innerColor` | Color? | The color of the inner, non-pulsing circle. Default is `null`. |
122 | | `innerSize` | double? | The size of the inner, non-pulsing circle. Default is `null`. |
123 | | `pulseCount` | int | The number of pulses to display. Default is `3`. |
124 | | `pulseDuration` | Duration | The duration of a single pulse animation. Default is `4` seconds. |
125 |
126 | ### `PulseStyle` properties
127 |
128 | | Property | Type | Description |
129 | |-----------------|---------------------|--------------------------------------------------------------------------------------------|
130 | | `color` | Color | Main pulse color. Default is `Colors.red`. |
131 | | `borderColor` | Color? | Pulse border color. If `null`, no border will be rendered. Default is `null`. |
132 | | `borderWidth` | double? | Pulse border width. If `null`, no border will be rendered. Default is `null`. |
133 | | `gradientStyle` | PulseGradientStyle? | If set, the pulse will be rendered as a gradient. Default is `null`. |
134 | | `pulseCurve` | Curve | Pulse scale animation curve. Default is `Curves.linear`. |
135 | | `opacityCurve` | Curve | Pulse opacity animation curve. Default is `Curves.linear`. |
136 | | `fadeOpacity` | bool | Whether the opacity should be animated from 1.0 to 0.0. Default is `true`. |
137 | | `startSize` | double | The size of the pulse when it begins, as a fraction of the pulse radius. Default is `0.0`. |
138 |
139 | ### `PulseGradientStyle` properties
140 |
141 | | Property | Type | Description |
142 | |-----------------|--------|----------------------------------------------------------------------------------------------------------------------------------------|
143 | | `radius` | double | The radius of the gradient, as a fraction pulse radius. Default is `0.5`. |
144 | | `start` | double | The start point of the gradient, as a fraction of the pulse radius. Default is `0.0`. |
145 | | `end` | double | The end point of the gradient, as a fraction of the pulse radius. Default is `1.0`. |
146 | | `startColor` | Color? | The start color of the gradient. If null, the pulse color will be used with the opacity set to `0.0`. Default is `null`. |
147 | | `reverseColors` | bool | Whether the gradient colors should be reversed. If `true`, the gradient will start from `end` and end at `start`. Default is `false`. |
148 |
149 | ### `PulseFit` enum
150 |
151 | | Value | Description |
152 | |-----------|---------------------------------------------------|
153 | | `contain` | The pulse will be scaled to fit the widget size. |
154 | | `cover` | The pulse will be scaled to fill the widget size. |
155 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | # Additional information about this file can be found at
4 | # https://dart.dev/guides/language/analysis-options
5 |
--------------------------------------------------------------------------------
/doc/example-looney-tunes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/example-looney-tunes.png
--------------------------------------------------------------------------------
/doc/example-pulse-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/example-pulse-icon.png
--------------------------------------------------------------------------------
/doc/example-splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/example-splash.png
--------------------------------------------------------------------------------
/doc/example-tunnel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/example-tunnel.png
--------------------------------------------------------------------------------
/doc/flutter-demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/flutter-demo.gif
--------------------------------------------------------------------------------
/doc/pulsator-icon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/pulsator-icon.gif
--------------------------------------------------------------------------------
/doc/pulsator-looney-tunes.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/pulsator-looney-tunes.gif
--------------------------------------------------------------------------------
/doc/pulsator-splash.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/pulsator-splash.gif
--------------------------------------------------------------------------------
/doc/pulsator-tunnel.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/doc/pulsator-tunnel.gif
--------------------------------------------------------------------------------
/example/.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 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .packages
31 | .pub-cache/
32 | .pub/
33 | /build/
34 |
35 | # Symbolication related
36 | app.*.symbols
37 |
38 | # Obfuscation related
39 | app.*.map.json
40 |
41 | # Android Studio will place build artifacts here
42 | /android/app/debug
43 | /android/app/profile
44 | /android/app/release
45 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
8 | channel: stable
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
17 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
18 | - platform: android
19 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
20 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
21 | - platform: ios
22 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
23 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
24 |
25 | # User provided section
26 |
27 | # List of Local paths (relative to this file) that should be
28 | # ignored by the migrate tool.
29 | #
30 | # Files that are not part of the templates will be ignored by default.
31 | unmanaged_files:
32 | - 'lib/main.dart'
33 | - 'ios/Runner.xcodeproj/project.pbxproj'
34 |
--------------------------------------------------------------------------------
/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 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/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 | ndkVersion flutter.ndkVersion
31 |
32 | compileOptions {
33 | sourceCompatibility JavaVersion.VERSION_1_8
34 | targetCompatibility JavaVersion.VERSION_1_8
35 | }
36 |
37 | kotlinOptions {
38 | jvmTarget = '1.8'
39 | }
40 |
41 | sourceSets {
42 | main.java.srcDirs += 'src/main/kotlin'
43 | }
44 |
45 | defaultConfig {
46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
47 | applicationId "com.example.example"
48 | // You can update the following values to match your application needs.
49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
50 | minSdkVersion flutter.minSdkVersion
51 | targetSdkVersion flutter.targetSdkVersion
52 | versionCode flutterVersionCode.toInteger()
53 | versionName flutterVersionName
54 | }
55 |
56 | buildTypes {
57 | release {
58 | // TODO: Add your own signing config for the release build.
59 | // Signing with the debug keys for now, so `flutter run --release` works.
60 | signingConfig signingConfigs.debug
61 | }
62 | }
63 | }
64 |
65 | flutter {
66 | source '../..'
67 | }
68 |
69 | dependencies {
70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
71 | }
72 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.7.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.2.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.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
6 |
--------------------------------------------------------------------------------
/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/assets/android_phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/example/assets/android_phone.png
--------------------------------------------------------------------------------
/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.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXCopyFilesBuildPhase section */
19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
20 | isa = PBXCopyFilesBuildPhase;
21 | buildActionMask = 2147483647;
22 | dstPath = "";
23 | dstSubfolderSpec = 10;
24 | files = (
25 | );
26 | name = "Embed Frameworks";
27 | runOnlyForDeploymentPostprocessing = 0;
28 | };
29 | /* End PBXCopyFilesBuildPhase section */
30 |
31 | /* Begin PBXFileReference section */
32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXFrameworksBuildPhase section */
56 |
57 | /* Begin PBXGroup section */
58 | 9740EEB11CF90186004384FC /* Flutter */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
65 | );
66 | name = Flutter;
67 | sourceTree = "";
68 | };
69 | 97C146E51CF9000F007C117D = {
70 | isa = PBXGroup;
71 | children = (
72 | 9740EEB11CF90186004384FC /* Flutter */,
73 | 97C146F01CF9000F007C117D /* Runner */,
74 | 97C146EF1CF9000F007C117D /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | 97C146EF1CF9000F007C117D /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 97C146EE1CF9000F007C117D /* Runner.app */,
82 | );
83 | name = Products;
84 | sourceTree = "";
85 | };
86 | 97C146F01CF9000F007C117D /* Runner */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
92 | 97C147021CF9000F007C117D /* Info.plist */,
93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
97 | );
98 | path = Runner;
99 | sourceTree = "";
100 | };
101 | /* End PBXGroup section */
102 |
103 | /* Begin PBXNativeTarget section */
104 | 97C146ED1CF9000F007C117D /* Runner */ = {
105 | isa = PBXNativeTarget;
106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
107 | buildPhases = (
108 | 9740EEB61CF901F6004384FC /* Run Script */,
109 | 97C146EA1CF9000F007C117D /* Sources */,
110 | 97C146EB1CF9000F007C117D /* Frameworks */,
111 | 97C146EC1CF9000F007C117D /* Resources */,
112 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
114 | );
115 | buildRules = (
116 | );
117 | dependencies = (
118 | );
119 | name = Runner;
120 | productName = Runner;
121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
122 | productType = "com.apple.product-type.application";
123 | };
124 | /* End PBXNativeTarget section */
125 |
126 | /* Begin PBXProject section */
127 | 97C146E61CF9000F007C117D /* Project object */ = {
128 | isa = PBXProject;
129 | attributes = {
130 | LastUpgradeCheck = 1300;
131 | ORGANIZATIONNAME = "";
132 | TargetAttributes = {
133 | 97C146ED1CF9000F007C117D = {
134 | CreatedOnToolsVersion = 7.3.1;
135 | LastSwiftMigration = 1100;
136 | };
137 | };
138 | };
139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
140 | compatibilityVersion = "Xcode 9.3";
141 | developmentRegion = en;
142 | hasScannedForEncodings = 0;
143 | knownRegions = (
144 | en,
145 | Base,
146 | );
147 | mainGroup = 97C146E51CF9000F007C117D;
148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
149 | projectDirPath = "";
150 | projectRoot = "";
151 | targets = (
152 | 97C146ED1CF9000F007C117D /* Runner */,
153 | );
154 | };
155 | /* End PBXProject section */
156 |
157 | /* Begin PBXResourcesBuildPhase section */
158 | 97C146EC1CF9000F007C117D /* Resources */ = {
159 | isa = PBXResourcesBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXResourcesBuildPhase section */
170 |
171 | /* Begin PBXShellScriptBuildPhase section */
172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
173 | isa = PBXShellScriptBuildPhase;
174 | alwaysOutOfDate = 1;
175 | buildActionMask = 2147483647;
176 | files = (
177 | );
178 | inputPaths = (
179 | );
180 | name = "Thin Binary";
181 | outputPaths = (
182 | );
183 | runOnlyForDeploymentPostprocessing = 0;
184 | shellPath = /bin/sh;
185 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
186 | };
187 | 9740EEB61CF901F6004384FC /* Run Script */ = {
188 | isa = PBXShellScriptBuildPhase;
189 | alwaysOutOfDate = 1;
190 | buildActionMask = 2147483647;
191 | files = (
192 | );
193 | inputPaths = (
194 | );
195 | name = "Run Script";
196 | outputPaths = (
197 | );
198 | runOnlyForDeploymentPostprocessing = 0;
199 | shellPath = /bin/sh;
200 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
201 | };
202 | /* End PBXShellScriptBuildPhase section */
203 |
204 | /* Begin PBXSourcesBuildPhase section */
205 | 97C146EA1CF9000F007C117D /* Sources */ = {
206 | isa = PBXSourcesBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
210 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
211 | );
212 | runOnlyForDeploymentPostprocessing = 0;
213 | };
214 | /* End PBXSourcesBuildPhase section */
215 |
216 | /* Begin PBXVariantGroup section */
217 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
218 | isa = PBXVariantGroup;
219 | children = (
220 | 97C146FB1CF9000F007C117D /* Base */,
221 | );
222 | name = Main.storyboard;
223 | sourceTree = "";
224 | };
225 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
226 | isa = PBXVariantGroup;
227 | children = (
228 | 97C147001CF9000F007C117D /* Base */,
229 | );
230 | name = LaunchScreen.storyboard;
231 | sourceTree = "";
232 | };
233 | /* End PBXVariantGroup section */
234 |
235 | /* Begin XCBuildConfiguration section */
236 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
237 | isa = XCBuildConfiguration;
238 | buildSettings = {
239 | ALWAYS_SEARCH_USER_PATHS = NO;
240 | CLANG_ANALYZER_NONNULL = YES;
241 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
242 | CLANG_CXX_LIBRARY = "libc++";
243 | CLANG_ENABLE_MODULES = YES;
244 | CLANG_ENABLE_OBJC_ARC = YES;
245 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
246 | CLANG_WARN_BOOL_CONVERSION = YES;
247 | CLANG_WARN_COMMA = YES;
248 | CLANG_WARN_CONSTANT_CONVERSION = YES;
249 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
250 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
251 | CLANG_WARN_EMPTY_BODY = YES;
252 | CLANG_WARN_ENUM_CONVERSION = YES;
253 | CLANG_WARN_INFINITE_RECURSION = YES;
254 | CLANG_WARN_INT_CONVERSION = YES;
255 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
256 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
257 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
258 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
259 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
260 | CLANG_WARN_STRICT_PROTOTYPES = YES;
261 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
262 | CLANG_WARN_UNREACHABLE_CODE = YES;
263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
264 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
265 | COPY_PHASE_STRIP = NO;
266 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
267 | ENABLE_NS_ASSERTIONS = NO;
268 | ENABLE_STRICT_OBJC_MSGSEND = YES;
269 | GCC_C_LANGUAGE_STANDARD = gnu99;
270 | GCC_NO_COMMON_BLOCKS = YES;
271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
273 | GCC_WARN_UNDECLARED_SELECTOR = YES;
274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
275 | GCC_WARN_UNUSED_FUNCTION = YES;
276 | GCC_WARN_UNUSED_VARIABLE = YES;
277 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
278 | MTL_ENABLE_DEBUG_INFO = NO;
279 | SDKROOT = iphoneos;
280 | SUPPORTED_PLATFORMS = iphoneos;
281 | TARGETED_DEVICE_FAMILY = "1,2";
282 | VALIDATE_PRODUCT = YES;
283 | };
284 | name = Profile;
285 | };
286 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
287 | isa = XCBuildConfiguration;
288 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
289 | buildSettings = {
290 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
291 | CLANG_ENABLE_MODULES = YES;
292 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
293 | ENABLE_BITCODE = NO;
294 | INFOPLIST_FILE = Runner/Info.plist;
295 | LD_RUNPATH_SEARCH_PATHS = (
296 | "$(inherited)",
297 | "@executable_path/Frameworks",
298 | );
299 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
300 | PRODUCT_NAME = "$(TARGET_NAME)";
301 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
302 | SWIFT_VERSION = 5.0;
303 | VERSIONING_SYSTEM = "apple-generic";
304 | };
305 | name = Profile;
306 | };
307 | 97C147031CF9000F007C117D /* Debug */ = {
308 | isa = XCBuildConfiguration;
309 | buildSettings = {
310 | ALWAYS_SEARCH_USER_PATHS = NO;
311 | CLANG_ANALYZER_NONNULL = YES;
312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
313 | CLANG_CXX_LIBRARY = "libc++";
314 | CLANG_ENABLE_MODULES = YES;
315 | CLANG_ENABLE_OBJC_ARC = YES;
316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
317 | CLANG_WARN_BOOL_CONVERSION = YES;
318 | CLANG_WARN_COMMA = YES;
319 | CLANG_WARN_CONSTANT_CONVERSION = YES;
320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
322 | CLANG_WARN_EMPTY_BODY = YES;
323 | CLANG_WARN_ENUM_CONVERSION = YES;
324 | CLANG_WARN_INFINITE_RECURSION = YES;
325 | CLANG_WARN_INT_CONVERSION = YES;
326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
327 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
328 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
330 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
331 | CLANG_WARN_STRICT_PROTOTYPES = YES;
332 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
333 | CLANG_WARN_UNREACHABLE_CODE = YES;
334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
336 | COPY_PHASE_STRIP = NO;
337 | DEBUG_INFORMATION_FORMAT = dwarf;
338 | ENABLE_STRICT_OBJC_MSGSEND = YES;
339 | ENABLE_TESTABILITY = YES;
340 | GCC_C_LANGUAGE_STANDARD = gnu99;
341 | GCC_DYNAMIC_NO_PIC = NO;
342 | GCC_NO_COMMON_BLOCKS = YES;
343 | GCC_OPTIMIZATION_LEVEL = 0;
344 | GCC_PREPROCESSOR_DEFINITIONS = (
345 | "DEBUG=1",
346 | "$(inherited)",
347 | );
348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
350 | GCC_WARN_UNDECLARED_SELECTOR = YES;
351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
352 | GCC_WARN_UNUSED_FUNCTION = YES;
353 | GCC_WARN_UNUSED_VARIABLE = YES;
354 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
355 | MTL_ENABLE_DEBUG_INFO = YES;
356 | ONLY_ACTIVE_ARCH = YES;
357 | SDKROOT = iphoneos;
358 | TARGETED_DEVICE_FAMILY = "1,2";
359 | };
360 | name = Debug;
361 | };
362 | 97C147041CF9000F007C117D /* Release */ = {
363 | isa = XCBuildConfiguration;
364 | buildSettings = {
365 | ALWAYS_SEARCH_USER_PATHS = NO;
366 | CLANG_ANALYZER_NONNULL = YES;
367 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
368 | CLANG_CXX_LIBRARY = "libc++";
369 | CLANG_ENABLE_MODULES = YES;
370 | CLANG_ENABLE_OBJC_ARC = YES;
371 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
372 | CLANG_WARN_BOOL_CONVERSION = YES;
373 | CLANG_WARN_COMMA = YES;
374 | CLANG_WARN_CONSTANT_CONVERSION = YES;
375 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
376 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
377 | CLANG_WARN_EMPTY_BODY = YES;
378 | CLANG_WARN_ENUM_CONVERSION = YES;
379 | CLANG_WARN_INFINITE_RECURSION = YES;
380 | CLANG_WARN_INT_CONVERSION = YES;
381 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
382 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
383 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
384 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
385 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
386 | CLANG_WARN_STRICT_PROTOTYPES = YES;
387 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
388 | CLANG_WARN_UNREACHABLE_CODE = YES;
389 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
390 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
391 | COPY_PHASE_STRIP = NO;
392 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
393 | ENABLE_NS_ASSERTIONS = NO;
394 | ENABLE_STRICT_OBJC_MSGSEND = YES;
395 | GCC_C_LANGUAGE_STANDARD = gnu99;
396 | GCC_NO_COMMON_BLOCKS = YES;
397 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
398 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
399 | GCC_WARN_UNDECLARED_SELECTOR = YES;
400 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
401 | GCC_WARN_UNUSED_FUNCTION = YES;
402 | GCC_WARN_UNUSED_VARIABLE = YES;
403 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
404 | MTL_ENABLE_DEBUG_INFO = NO;
405 | SDKROOT = iphoneos;
406 | SUPPORTED_PLATFORMS = iphoneos;
407 | SWIFT_COMPILATION_MODE = wholemodule;
408 | SWIFT_OPTIMIZATION_LEVEL = "-O";
409 | TARGETED_DEVICE_FAMILY = "1,2";
410 | VALIDATE_PRODUCT = YES;
411 | };
412 | name = Release;
413 | };
414 | 97C147061CF9000F007C117D /* Debug */ = {
415 | isa = XCBuildConfiguration;
416 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
417 | buildSettings = {
418 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
419 | CLANG_ENABLE_MODULES = YES;
420 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
421 | ENABLE_BITCODE = NO;
422 | INFOPLIST_FILE = Runner/Info.plist;
423 | LD_RUNPATH_SEARCH_PATHS = (
424 | "$(inherited)",
425 | "@executable_path/Frameworks",
426 | );
427 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
428 | PRODUCT_NAME = "$(TARGET_NAME)";
429 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
430 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
431 | SWIFT_VERSION = 5.0;
432 | VERSIONING_SYSTEM = "apple-generic";
433 | };
434 | name = Debug;
435 | };
436 | 97C147071CF9000F007C117D /* Release */ = {
437 | isa = XCBuildConfiguration;
438 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
439 | buildSettings = {
440 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
441 | CLANG_ENABLE_MODULES = YES;
442 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
443 | ENABLE_BITCODE = NO;
444 | INFOPLIST_FILE = Runner/Info.plist;
445 | LD_RUNPATH_SEARCH_PATHS = (
446 | "$(inherited)",
447 | "@executable_path/Frameworks",
448 | );
449 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
450 | PRODUCT_NAME = "$(TARGET_NAME)";
451 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
452 | SWIFT_VERSION = 5.0;
453 | VERSIONING_SYSTEM = "apple-generic";
454 | };
455 | name = Release;
456 | };
457 | /* End XCBuildConfiguration section */
458 |
459 | /* Begin XCConfigurationList section */
460 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
461 | isa = XCConfigurationList;
462 | buildConfigurations = (
463 | 97C147031CF9000F007C117D /* Debug */,
464 | 97C147041CF9000F007C117D /* Release */,
465 | 249021D3217E4FDB00AE95B9 /* Profile */,
466 | );
467 | defaultConfigurationIsVisible = 0;
468 | defaultConfigurationName = Release;
469 | };
470 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
471 | isa = XCConfigurationList;
472 | buildConfigurations = (
473 | 97C147061CF9000F007C117D /* Debug */,
474 | 97C147071CF9000F007C117D /* Release */,
475 | 249021D4217E4FDB00AE95B9 /* Profile */,
476 | );
477 | defaultConfigurationIsVisible = 0;
478 | defaultConfigurationName = Release;
479 | };
480 | /* End XCConfigurationList section */
481 | };
482 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
483 | }
484 |
--------------------------------------------------------------------------------
/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/booncol/pulsator/30f31fa9c5c7bb5f8c22a6df0fd857ede7b1cadc/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 | import 'package:pulsator/pulsator.dart';
3 |
4 | void main() {
5 | runApp(const MyApp());
6 | }
7 |
8 | class MyApp extends StatelessWidget {
9 | const MyApp({super.key});
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return MaterialApp(
14 | title: 'Pulsator example',
15 | theme: ThemeData(primarySwatch: Colors.blue),
16 | home: const MyHomePage(),
17 | );
18 | }
19 | }
20 |
21 | class MyHomePage extends StatefulWidget {
22 | const MyHomePage({super.key});
23 |
24 | @override
25 | State createState() => _MyHomePageState();
26 | }
27 |
28 | class _MyHomePageState extends State {
29 | int _count = 4;
30 | int _duration = 3;
31 | int _repeatCount = 0;
32 |
33 | void _handleCountChanged(double value) =>
34 | setState(() => _count = value.toInt());
35 |
36 | void _handleDurationChanged(double value) =>
37 | setState(() => _duration = value.toInt());
38 |
39 | void _handleRepeatCountChanged(double value) =>
40 | setState(() => _repeatCount = value.toInt());
41 |
42 | @override
43 | Widget build(BuildContext context) {
44 | return Scaffold(
45 | appBar: AppBar(title: const Text('Pulsator')),
46 | body: SafeArea(
47 | bottom: true,
48 | child: Column(
49 | children: [
50 | Expanded(
51 | child: Stack(
52 | children: [
53 | Pulsator(
54 | style: const PulseStyle(color: Colors.red),
55 | count: _count,
56 | duration: Duration(seconds: _duration),
57 | repeat: _repeatCount,
58 | ),
59 | Center(
60 | child: Image.asset(
61 | 'assets/android_phone.png',
62 | width: 128,
63 | height: 128,
64 | ),
65 | ),
66 | ],
67 | ),
68 | ),
69 | Padding(
70 | padding: const EdgeInsets.all(24),
71 | child: _Controls(
72 | count: _count,
73 | duration: _duration,
74 | repeatCount: _repeatCount,
75 | onCountChanged: _handleCountChanged,
76 | onDurationChanged: _handleDurationChanged,
77 | onRepeatCountChanged: _handleRepeatCountChanged,
78 | ),
79 | ),
80 | ],
81 | ),
82 | ),
83 | );
84 | }
85 | }
86 |
87 | class _Controls extends StatelessWidget {
88 | const _Controls({
89 | required this.count,
90 | required this.duration,
91 | required this.repeatCount,
92 | required this.onCountChanged,
93 | required this.onDurationChanged,
94 | required this.onRepeatCountChanged,
95 | });
96 |
97 | final int count;
98 | final int duration;
99 | final int repeatCount;
100 | final ValueChanged onCountChanged;
101 | final ValueChanged onDurationChanged;
102 | final ValueChanged onRepeatCountChanged;
103 |
104 | @override
105 | Widget build(BuildContext context) {
106 | return Table(
107 | defaultVerticalAlignment: TableCellVerticalAlignment.middle,
108 | columnWidths: const {
109 | 0: FixedColumnWidth(70),
110 | 1: FlexColumnWidth(),
111 | 2: FixedColumnWidth(30),
112 | },
113 | children: [
114 | TableRow(
115 | children: [
116 | const Text('Count', textAlign: TextAlign.right),
117 | Slider(
118 | value: count.toDouble(),
119 | min: 1,
120 | max: 9,
121 | onChanged: onCountChanged,
122 | ),
123 | Text(count.toString()),
124 | ],
125 | ),
126 | TableRow(
127 | children: [
128 | const Text('Duration', textAlign: TextAlign.right),
129 | Slider(
130 | value: duration.toDouble(),
131 | min: 1,
132 | max: 6,
133 | onChanged: onDurationChanged,
134 | ),
135 | Text(duration.toString()),
136 | ],
137 | ),
138 | TableRow(
139 | children: [
140 | const Text('Repeats', textAlign: TextAlign.right),
141 | Slider(
142 | value: repeatCount.toDouble(),
143 | min: 0,
144 | max: 10,
145 | onChanged: onRepeatCountChanged,
146 | ),
147 | Text(repeatCount.toString()),
148 | ],
149 | ),
150 | ],
151 | );
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.10.0"
12 | boolean_selector:
13 | dependency: transitive
14 | description:
15 | name: boolean_selector
16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.1.1"
20 | characters:
21 | dependency: transitive
22 | description:
23 | name: characters
24 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "1.2.1"
28 | clock:
29 | dependency: transitive
30 | description:
31 | name: clock
32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.1.1"
36 | collection:
37 | dependency: transitive
38 | description:
39 | name: collection
40 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.17.0"
44 | cupertino_icons:
45 | dependency: "direct main"
46 | description:
47 | name: cupertino_icons
48 | sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.0.6"
52 | fake_async:
53 | dependency: transitive
54 | description:
55 | name: fake_async
56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.3.1"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_lints:
66 | dependency: "direct dev"
67 | description:
68 | name: flutter_lints
69 | sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
70 | url: "https://pub.dev"
71 | source: hosted
72 | version: "2.0.3"
73 | flutter_test:
74 | dependency: "direct dev"
75 | description: flutter
76 | source: sdk
77 | version: "0.0.0"
78 | js:
79 | dependency: transitive
80 | description:
81 | name: js
82 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
83 | url: "https://pub.dev"
84 | source: hosted
85 | version: "0.6.5"
86 | lints:
87 | dependency: transitive
88 | description:
89 | name: lints
90 | sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
91 | url: "https://pub.dev"
92 | source: hosted
93 | version: "2.0.1"
94 | matcher:
95 | dependency: transitive
96 | description:
97 | name: matcher
98 | sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
99 | url: "https://pub.dev"
100 | source: hosted
101 | version: "0.12.13"
102 | material_color_utilities:
103 | dependency: transitive
104 | description:
105 | name: material_color_utilities
106 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "0.2.0"
110 | meta:
111 | dependency: transitive
112 | description:
113 | name: meta
114 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "1.8.0"
118 | path:
119 | dependency: transitive
120 | description:
121 | name: path
122 | sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "1.8.2"
126 | pulsator:
127 | dependency: "direct main"
128 | description:
129 | path: ".."
130 | relative: true
131 | source: path
132 | version: "0.0.1"
133 | sky_engine:
134 | dependency: transitive
135 | description: flutter
136 | source: sdk
137 | version: "0.0.99"
138 | source_span:
139 | dependency: transitive
140 | description:
141 | name: source_span
142 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
143 | url: "https://pub.dev"
144 | source: hosted
145 | version: "1.9.1"
146 | stack_trace:
147 | dependency: transitive
148 | description:
149 | name: stack_trace
150 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
151 | url: "https://pub.dev"
152 | source: hosted
153 | version: "1.11.0"
154 | stream_channel:
155 | dependency: transitive
156 | description:
157 | name: stream_channel
158 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
159 | url: "https://pub.dev"
160 | source: hosted
161 | version: "2.1.1"
162 | string_scanner:
163 | dependency: transitive
164 | description:
165 | name: string_scanner
166 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
167 | url: "https://pub.dev"
168 | source: hosted
169 | version: "1.2.0"
170 | term_glyph:
171 | dependency: transitive
172 | description:
173 | name: term_glyph
174 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
175 | url: "https://pub.dev"
176 | source: hosted
177 | version: "1.2.1"
178 | test_api:
179 | dependency: transitive
180 | description:
181 | name: test_api
182 | sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
183 | url: "https://pub.dev"
184 | source: hosted
185 | version: "0.4.16"
186 | vector_math:
187 | dependency: transitive
188 | description:
189 | name: vector_math
190 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
191 | url: "https://pub.dev"
192 | source: hosted
193 | version: "2.1.4"
194 | sdks:
195 | dart: ">=2.19.0 <4.0.0"
196 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: example
2 | description: A new Flutter project.
3 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
4 | version: 1.0.0+1
5 |
6 | environment:
7 | sdk: '>=2.19.0 <3.0.0'
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 |
13 | cupertino_icons: ^1.0.2
14 | pulsator:
15 | path: ../
16 |
17 | dev_dependencies:
18 | flutter_test:
19 | sdk: flutter
20 |
21 | flutter_lints: ^2.0.0
22 |
23 | flutter:
24 | uses-material-design: true
25 | assets:
26 | - assets/
--------------------------------------------------------------------------------
/lib/pulsator.dart:
--------------------------------------------------------------------------------
1 | library pulsator;
2 |
3 | export 'src/pulsator.dart';
4 | export 'src/styles.dart';
5 | export 'src/pulse_icon.dart';
6 |
--------------------------------------------------------------------------------
/lib/src/pulsator.dart:
--------------------------------------------------------------------------------
1 | /// Copyright 2023 Lukasz Majda (lukasz.majda@gmail.com)
2 | ///
3 | ///
4 |
5 | import 'package:flutter/material.dart';
6 | import 'package:pulsator/src/styles.dart';
7 |
8 | const _kOverdrawFactor = 1.4142135624;
9 |
10 | typedef OnCreatedListener = void Function(AnimationController controller);
11 |
12 | /// Pulsator widget that renders pulsating circles.
13 | ///
14 | /// The widget can be configured to render a given number of pulsating circles
15 | /// with a given [style].
16 | ///
17 | /// The [count] property controls the number of circles rendered at a time.
18 | ///
19 | /// The [duration] property controls the duration of a single pulse animation.
20 | ///
21 | /// The [repeat] property controls the number of times the animation will
22 | /// repeat. If 0, the animation will repeat forever.
23 | ///
24 | /// The [startFromScratch] property controls if the animation should start from
25 | /// the beginning.
26 | ///
27 | /// The [autoStart] property controls if the animation should start
28 | /// automatically when the widget is created.
29 | ///
30 | /// The [fit] property controls how the pulse should be scaled to fit the
31 | /// widget size. The [onCreated] callback is invoked when the animation
32 | /// controller is created.
33 | ///
34 | /// The [onCompleted] callback is invoked when the animation is completed.
35 | ///
36 | /// The [child] property is the child of the widget that is rendered on top of
37 | /// the pulses.
38 | class Pulsator extends StatefulWidget {
39 | /// Make a new [Pulsator] instance.
40 | const Pulsator({
41 | required this.style,
42 | this.count = 3,
43 | this.duration = const Duration(seconds: 2),
44 | this.repeat = 0,
45 | this.startFromScratch = true,
46 | this.autoStart = true,
47 | this.fit = PulseFit.contain,
48 | this.onCreated,
49 | this.onCompleted,
50 | this.child,
51 | super.key,
52 | }) : assert(count > 0),
53 | assert(repeat >= 0);
54 |
55 | /// Pulse style configuration.
56 | final PulseStyle style;
57 |
58 | /// Number of pulses visible at a time. Default is 3.
59 | final int count;
60 |
61 | /// Duration of a single pulse animation. Default is 2 seconds.
62 | final Duration duration;
63 |
64 | /// Number of times pulses will repeat. If 0, pulses will repeat forever.
65 | /// Default is 0.
66 | final int repeat;
67 |
68 | /// Whether the animation should start from the beginning. Default is true.
69 | final bool startFromScratch;
70 |
71 | /// Whether the animation should start automatically when the widget is created.
72 | /// Default is true.
73 | final bool autoStart;
74 |
75 | /// How the pulse should be scaled to fit the widget size.
76 | /// Default is [PulseFit.contain].
77 | final PulseFit fit;
78 |
79 | /// Invoked when the animation controller is created.
80 | final OnCreatedListener? onCreated;
81 |
82 | /// Invoked when the animation is completed.
83 | final VoidCallback? onCompleted;
84 |
85 | /// The child of the widget that is rendered on top of the pulses.
86 | final Widget? child;
87 |
88 | @override
89 | State createState() => _PulsatorViewState();
90 | }
91 |
92 | class _PulsatorViewState extends State
93 | with SingleTickerProviderStateMixin {
94 | AnimationController? _controller;
95 | late Animation _animation;
96 | final int _counter = 0;
97 | double _scaleFactor = 1.0;
98 | late double? _minProgress;
99 |
100 | @override
101 | void initState() {
102 | super.initState();
103 | _buildAnimation();
104 | }
105 |
106 | @override
107 | void dispose() {
108 | _controller?.dispose();
109 | super.dispose();
110 | }
111 |
112 | @override
113 | void didUpdateWidget(covariant Pulsator oldWidget) {
114 | // Recalculate the scale factor.
115 | if (widget.fit == PulseFit.cover) {
116 | _scaleFactor = (widget.count > 1
117 | ? 1.0 /
118 | widget.style.pulseCurve.transform(
119 | (widget.count - 1) / widget.count,
120 | )
121 | : 1.0) *
122 | _kOverdrawFactor;
123 | } else {
124 | _scaleFactor = 1.0;
125 | }
126 |
127 | // Rebuild the animation if necessary.
128 | if (widget.repeat != oldWidget.repeat ||
129 | widget.duration != oldWidget.duration ||
130 | widget.startFromScratch != oldWidget.startFromScratch ||
131 | widget.autoStart != oldWidget.autoStart ||
132 | widget.count != oldWidget.count) {
133 | _buildAnimation();
134 | }
135 |
136 | super.didUpdateWidget(oldWidget);
137 | }
138 |
139 | /// Build animation controller and animation based on widget configuration.
140 | void _buildAnimation() {
141 | // Calculate animation end value based on repeat count and pulse count.
142 | late final double animEnd;
143 | if (widget.repeat > 0) {
144 | animEnd = widget.repeat + 1.0 - 1.0 / widget.count;
145 | } else {
146 | animEnd = 1.0;
147 | }
148 |
149 | // Create animation controller and animation if not already created.
150 | // Otherwise, update only the animation duration.
151 | final firstBuild = _controller == null;
152 | final duration = (widget.duration.inMilliseconds * animEnd).toInt();
153 | if (_controller == null) {
154 | _controller = AnimationController(
155 | duration: Duration(milliseconds: duration),
156 | vsync: this,
157 | )..addStatusListener(_handleAnimationStatus);
158 | } else {
159 | _controller!.duration = Duration(milliseconds: duration);
160 | }
161 |
162 | _animation = Tween(begin: 0.0, end: animEnd).animate(_controller!);
163 | _minProgress = widget.startFromScratch ? 0.0 : null;
164 |
165 | // Start animation if autoStart is true.
166 | if (widget.autoStart) {
167 | _controller!.reset();
168 | _controller!.forward();
169 | }
170 |
171 | // Invoke onCreated callback if it is a first build.
172 | if (firstBuild && widget.onCreated != null) {
173 | widget.onCreated!.call(_controller!);
174 | }
175 | }
176 |
177 | /// Handle animation status changes to reset the animation if necessary.
178 | void _handleAnimationStatus(AnimationStatus status) {
179 | if (status != AnimationStatus.completed) {
180 | return;
181 | }
182 |
183 | if (widget.repeat > 0) {
184 | // Animation is completed so invoke the callback.
185 | widget.onCompleted?.call();
186 | return;
187 | }
188 |
189 | // It's another animation cycle, so don't clamp the progress.
190 | _minProgress = null;
191 |
192 | _controller!.reset();
193 | _controller!.forward();
194 | }
195 |
196 | @override
197 | Widget build(BuildContext context) {
198 | final pulse = AnimatedBuilder(
199 | animation: _animation,
200 | builder: (context, child) {
201 | final pulses = [
202 | for (var i = 0; i < widget.count; i++)
203 | _PulseCircle(
204 | style: widget.style,
205 | scale: _animation.value,
206 | offset: i / widget.count,
207 | progress: _counter + _animation.value,
208 | minProgress: _minProgress,
209 | maxProgress: widget.repeat > 0 ? widget.repeat.toDouble() : null,
210 | scaleFactor: _scaleFactor,
211 | ),
212 | ];
213 | // Pulses should be rendered in order from the biggest to the smallest.
214 | pulses.sort(_compareZIndex);
215 |
216 | return Stack(
217 | alignment: Alignment.center,
218 | fit: StackFit.expand,
219 | children: pulses.map((e) => e).toList(growable: false),
220 | );
221 | },
222 | );
223 |
224 | // If there is no child, just return the pulse.
225 | if (widget.child == null) {
226 | return pulse;
227 | }
228 |
229 | return Stack(
230 | alignment: Alignment.center,
231 | children: [
232 | pulse,
233 | widget.child!,
234 | ],
235 | );
236 | }
237 |
238 | /// Compare two pulses by their z-index.
239 | static int _compareZIndex(_PulseCircle a, _PulseCircle b) {
240 | final ta = (a.progress - a.offset) % 1.0;
241 | final tb = (b.progress - b.offset) % 1.0;
242 | return tb.compareTo(ta);
243 | }
244 | }
245 |
246 | class _PulseCircle extends StatelessWidget {
247 | const _PulseCircle({
248 | required this.style,
249 | required this.scale,
250 | required this.offset,
251 | required this.progress,
252 | this.minProgress,
253 | this.maxProgress,
254 | this.scaleFactor = 1.0,
255 | }) : assert(scale >= 0.0),
256 | assert(offset >= 0.0),
257 | assert(progress >= 0.0),
258 | assert(scaleFactor > 0.0);
259 |
260 | /// Pulse style configuration.
261 | final PulseStyle style;
262 |
263 | /// Current animation scale value.
264 | final double scale;
265 |
266 | /// Offset of the pulse in the animation cycle.
267 | final double offset;
268 |
269 | /// Current animation progress value.
270 | final double progress;
271 |
272 | /// Minimum animation progress value to render the pulse.
273 | final double? minProgress;
274 |
275 | /// Maximum animation progress value to render the pulse.
276 | final double? maxProgress;
277 |
278 | /// Scale factor to apply to the pulse. Used when the pulse is rendered
279 | /// to fill the entire widget.
280 | final double scaleFactor;
281 |
282 | @override
283 | Widget build(BuildContext context) {
284 | // Calculate the current pulse progress, taking into account the offset.
285 | final progress = this.progress - offset;
286 |
287 | // If minProgress or maxProgress are set, check if the pulse should be
288 | // rendered.
289 | if ((minProgress != null && progress < minProgress!) ||
290 | (maxProgress != null && progress > maxProgress!)) {
291 | return const SizedBox.shrink();
292 | }
293 |
294 | // Make sure the progress is between 0.0 and 1.0.
295 | final t = progress % 1.0;
296 | final opacity =
297 | style.fadeOpacity ? 1.0 - style.opacityCurve.transform(t) : 1.0;
298 | final scale = style.startSize +
299 | style.pulseCurve.transform(t) * scaleFactor * (1.0 - style.startSize);
300 |
301 | return Transform.scale(
302 | scale: scale,
303 | child: Container(
304 | decoration: BoxDecoration(
305 | shape: BoxShape.circle,
306 | color: style.gradientStyle == null
307 | ? style.color.withOpacity(opacity)
308 | : null,
309 | gradient: style.gradientStyle != null
310 | ? RadialGradient(
311 | radius: style.gradientStyle!.radius,
312 | stops: [style.gradientStyle!.start, style.gradientStyle!.end],
313 | colors: style.gradientStyle!.reverseColors
314 | ? [
315 | style.color.withOpacity(opacity),
316 | style.gradientStyle!.startColor != null
317 | ? style.gradientStyle!.startColor!
318 | .withOpacity(opacity)
319 | : style.color.withOpacity(0),
320 | ]
321 | : [
322 | style.gradientStyle!.startColor != null
323 | ? style.gradientStyle!.startColor!
324 | .withOpacity(opacity)
325 | : style.color.withOpacity(0),
326 | style.color.withOpacity(opacity),
327 | ])
328 | : null,
329 | border: style.borderWidth != null && style.borderColor != null
330 | ? Border.all(
331 | color: style.borderColor!.withOpacity(opacity),
332 | width: style.borderWidth!,
333 | )
334 | : null,
335 | ),
336 | ),
337 | );
338 | }
339 | }
340 |
--------------------------------------------------------------------------------
/lib/src/pulse_icon.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:pulsator/src/pulsator.dart';
3 | import 'package:pulsator/src/styles.dart';
4 |
5 | /// A widget that displays an icon with a pulsing effect.
6 | ///
7 | /// The icon is displayed in the center of the widget. The pulsing effect is
8 | /// displayed as a circle around the icon.
9 | ///
10 | /// [icon] is the icon to display. Required.
11 | ///
12 | /// [iconColor] is the color of the icon. Default is white.
13 | ///
14 | /// [iconSize] is the size of the icon. Default is 24.
15 | ///
16 | /// [innerColor] is the color of the inner, non-pulsing circle. Default is the
17 | /// pulse color.
18 | ///
19 | /// [innerSize] is the size of the inner, non-pulsing circle. Default is the
20 | /// icon size.
21 | ///
22 | /// [pulseColor] is the color of the pulse.
23 | ///
24 | /// [pulseSize] is the size of the pulse. Default is 64.
25 | ///
26 | /// [pulseCount] is the number of pulses to display. Default is 3.
27 | ///
28 | /// [pulseDuration] is the duration of a single pulse animation. Default is 4
29 | /// seconds.
30 | ///
31 | /// Example:
32 | /// ```dart
33 | /// PulseIcon(
34 | /// icon: Icons.favorite,
35 | /// pulseColor: Colors.red,
36 | /// pulseCount: 5,
37 | /// pulseDuration: Duration(seconds: 2),
38 | /// iconColor: Colors.white,
39 | /// iconSize: 44,
40 | /// innerSize: 54,
41 | /// pulseSize: 116,
42 | /// )
43 | /// ```
44 | class PulseIcon extends StatelessWidget {
45 | const PulseIcon({
46 | required this.icon,
47 | required this.pulseColor,
48 | this.iconColor = Colors.white,
49 | this.iconSize = 24,
50 | this.pulseSize = 64,
51 | this.innerColor,
52 | this.innerSize,
53 | this.pulseCount = 3,
54 | this.pulseDuration = const Duration(seconds: 4),
55 | super.key,
56 | }) : assert(pulseCount > 0),
57 | assert(pulseSize > 0.0),
58 | assert(iconSize > 0.0);
59 |
60 | /// The icon to display.
61 | final IconData icon;
62 |
63 | /// The color of the icon. Default is white.
64 | final Color iconColor;
65 |
66 | /// The size of the icon. Default is 24.
67 | final double iconSize;
68 |
69 | /// The color of the inner, non-pulsing circle. Default is the pulse color.
70 | final Color? innerColor;
71 |
72 | /// The size of the inner, non-pulsing circle. Default is the icon size.
73 | final double? innerSize;
74 |
75 | /// The color of the pulse.
76 | final Color pulseColor;
77 |
78 | /// The size of the pulse. Default is 64.
79 | final double pulseSize;
80 |
81 | /// The number of pulses to display. Default is 3.
82 | final int pulseCount;
83 |
84 | /// The duration of a single pulse animation. Default is 4 seconds.
85 | final Duration pulseDuration;
86 |
87 | @override
88 | Widget build(BuildContext context) {
89 | final innerSize = this.innerSize ?? iconSize;
90 | return SizedBox(
91 | width: pulseSize,
92 | height: pulseSize,
93 | child: Pulsator(
94 | count: pulseCount,
95 | duration: pulseDuration,
96 | startFromScratch: false,
97 | style: PulseStyle(
98 | color: pulseColor,
99 | startSize: innerSize / pulseSize,
100 | // scaleCurve: Curves.easeOut,
101 | ),
102 | child: Stack(
103 | alignment: Alignment.center,
104 | children: [
105 | if (innerSize > 0.0)
106 | Container(
107 | width: innerSize,
108 | height: innerSize,
109 | decoration: BoxDecoration(
110 | color: innerColor ?? pulseColor,
111 | shape: BoxShape.circle,
112 | ),
113 | ),
114 | Icon(icon, color: iconColor, size: iconSize),
115 | ],
116 | ),
117 | ),
118 | );
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib/src/styles.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// How the pulse should be scaled to fit the widget size.
4 | enum PulseFit {
5 | /// The pulse will be scaled to fit the widget size.
6 | contain,
7 |
8 | /// The pulse will be scaled to fill the widget size.
9 | cover,
10 | }
11 |
12 | /// The style of the pulse gradient.
13 | ///
14 | /// [radius] is the radius of the gradient, as a fraction pulse radius.
15 | ///
16 | /// [start] is the start point of the gradient, as a fraction of the pulse
17 | /// radius.
18 | ///
19 | /// [end] is the end point of the gradient, as a fraction of the pulse radius.
20 | ///
21 | /// [startColor] is the start color of the gradient. If null, the pulse color
22 | /// will be used with the opacity set to 0.0.
23 | ///
24 | /// [reverseColors] is if the gradient colors should be reversed. If true, the
25 | /// gradient will start from [end] and end at [start].
26 | class PulseGradientStyle {
27 | /// Make a new [PulseGradientStyle] instance.
28 | const PulseGradientStyle({
29 | this.radius = 0.5,
30 | this.start = 0.0,
31 | this.end = 1.0,
32 | this.startColor,
33 | this.reverseColors = false,
34 | }) : assert(radius >= 0.0 && radius <= 1.0),
35 | assert(start >= 0.0 && start <= 1.0),
36 | assert(end >= 0.0 && end <= 1.0);
37 |
38 | /// The radius of the gradient, as a fraction pulse radius. Default is 0.5.
39 | final double radius;
40 |
41 | /// The start point of the gradient, as a fraction of the pulse radius.
42 | /// Default is 0.0.
43 | final double start;
44 |
45 | /// The end point of the gradient, as a fraction of the pulse radius. Default
46 | /// is 1.0.
47 | final double end;
48 |
49 | /// The start color of the gradient. If null, the pulse color will be used
50 | /// with the opacity set to 0.0.
51 | final Color? startColor;
52 |
53 | /// Whether the gradient colors should be reversed. If true, the gradient will
54 | /// start from [end] and end at [start]. Default is false.
55 | final bool reverseColors;
56 | }
57 |
58 | /// The style of the pulse.
59 | ///
60 | /// [color] is the main color of the pulse.
61 | ///
62 | /// [borderColor] is the border color of the pulse.
63 | ///
64 | /// [borderWidth] is the border width of the pulse. If 0, no border will be
65 | /// rendered.
66 | ///
67 | /// [gradientStyle] is the gradient style of the pulse. If null, no gradient
68 | /// will be rendered.
69 | ///
70 | /// [pulseCurve] is the pulse scale animation curve (default is linear).
71 | ///
72 | /// [opacityCurve] is the pulse opacity animation curve (default is linear).
73 | ///
74 | /// [fadeOpacity] is if the opacity should be animated from 1.0 to 0.0. Default
75 | ///
76 | /// [startSize] is the size of the pulse when it begins, as a fraction of the
77 | /// pulse radius. Default is 0.0.
78 | class PulseStyle {
79 | /// Make a new [PulseStyle] instance.
80 | const PulseStyle({
81 | this.color = Colors.red,
82 | this.borderColor,
83 | this.borderWidth,
84 | this.gradientStyle,
85 | this.pulseCurve = Curves.linear,
86 | this.opacityCurve = Curves.linear,
87 | this.fadeOpacity = true,
88 | this.startSize = 0.0,
89 | }) : assert(startSize >= 0.0 && startSize <= 1.0);
90 |
91 | /// Main pulse color.
92 | final Color color;
93 |
94 | /// Pulse border color. If `null`, no border will be rendered.
95 | final Color? borderColor;
96 |
97 | /// Pulse border width. If `null`, no border will be rendered.
98 | final double? borderWidth;
99 |
100 | /// If set, the pulse will be rendered as a gradient.
101 | final PulseGradientStyle? gradientStyle;
102 |
103 | /// Pulse scale animation curve (default is linear).
104 | final Curve pulseCurve;
105 |
106 | /// Pulse opacity animation curve (default is linear).
107 | final Curve opacityCurve;
108 |
109 | /// Whether the opacity should be animated from 1.0 to 0.0. Default is true.
110 | final bool fadeOpacity;
111 |
112 | /// The size of the pulse when it begins, as a fraction of the pulse radius.
113 | /// Default is 0.0.
114 | final double startSize;
115 | }
116 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: pulsator
2 | description: "Pulse animation for Flutter."
3 | version: 1.0.0+2
4 | homepage: https://github.com/booncol/pulsator
5 | repository: https://github.com/booncol/pulsator
6 | issue_tracker: https://github.com/booncol/pulsator/issues
7 |
8 | environment:
9 | sdk: ">=2.19.0 <3.0.0"
10 | flutter: ">=3.0.0"
11 |
12 | dependencies:
13 | flutter:
14 | sdk: flutter
15 |
16 | dev_dependencies:
17 | flutter_test:
18 | sdk: flutter
19 | flutter_lints: ^2.0.0
20 |
21 | flutter:
22 | uses-material-design: true
23 |
--------------------------------------------------------------------------------