├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── jackjonson │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ ├── launch_background.xml │ │ │ │ └── normal_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 │ ├── ic_error.json │ ├── ic_fail.png │ ├── ic_success.json │ ├── ic_success.png │ └── ic_success.svg ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── main.m ├── lib │ ├── blur_transition.dart │ ├── custom_toast_content_widget.dart │ └── main.dart ├── pubspec.yaml └── test │ └── widget_test.dart ├── lib ├── flutter_styled_toast.dart └── src │ ├── custom_animation.dart │ ├── custom_size_transition.dart │ ├── styled_toast.dart │ ├── styled_toast_enum.dart │ ├── styled_toast_manage.dart │ └── styled_toast_theme.dart ├── pubspec.yaml ├── screenshots ├── CustomFailToastWidget.gif ├── CustomSuccessToastWidget.gif ├── CustomToastWidget.gif ├── DefaultToastWidget.gif ├── FadeAnim.gif ├── FadeRotateAnim.gif ├── FadeScaleAnim.gif ├── OnDismiss.gif ├── OverallAnimations.gif ├── RotateAnim.gif ├── ScaleAnim.gif ├── ScaleRotateAnim.gif ├── SlideFromBottomAnim.gif ├── SlideFromLeftAnim.gif ├── SlideFromRightAnim.gif └── SlideFromTopAnim.gif ├── start_build_release_apk.bat └── test ├── custom_animation_test.dart ├── custom_size_transition_test.dart ├── styled_toast_manage_test.dart ├── styled_toast_test.dart └── styled_toast_theme_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | pubspec.lock 30 | 31 | # Android related 32 | **/android/**/gradle-wrapper.jar 33 | **/android/.gradle 34 | **/android/captures/ 35 | **/android/gradlew 36 | **/android/gradlew.bat 37 | **/android/local.properties 38 | **/android/**/GeneratedPluginRegistrant.java 39 | 40 | # iOS/XCode related 41 | **/ios/**/*.mode1v3 42 | **/ios/**/*.mode2v3 43 | **/ios/**/*.moved-aside 44 | **/ios/**/*.pbxuser 45 | **/ios/**/*.perspectivev3 46 | **/ios/**/*sync/ 47 | **/ios/**/.sconsign.dblite 48 | **/ios/**/.tags* 49 | **/ios/**/.vagrant/ 50 | **/ios/**/DerivedData/ 51 | **/ios/**/Icon? 52 | **/ios/**/Pods/ 53 | **/ios/**/.symlinks/ 54 | **/ios/**/profile 55 | **/ios/**/xcuserdata 56 | **/ios/.generated/ 57 | **/ios/Flutter/App.framework 58 | **/ios/Flutter/Flutter.framework 59 | **/ios/Flutter/Generated.xcconfig 60 | **/ios/Flutter/app.flx 61 | **/ios/Flutter/app.zip 62 | **/ios/Flutter/flutter_assets/ 63 | **/ios/ServiceDefinitions.json 64 | **/ios/Runner/GeneratedPluginRegistrant.* 65 | 66 | # Exceptions to above rules. 67 | !**/ios/**/default.mode1v3 68 | !**/ios/**/default.mode2v3 69 | !**/ios/**/default.pbxuser 70 | !**/ios/**/default.perspectivev3 71 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 72 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [2.2.1 null-safety] 2 | Fix warnings. 3 | 4 | 5 | ## [2.2.0 null-safety] 6 | Upgrade to Flutter 3.10.x. 7 | 8 | 9 | ## [2.1.3 null-safety] 10 | Fix warnings. 11 | 12 | 13 | ## [2.1.2 null-safety] 14 | Add multiple animation demo in the example. 15 | Upgrade example android embedding to v2. 16 | Fix warnings. 17 | 18 | 19 | ## [2.0.0 null-safety] 20 | Migrate to null safety. 21 | Remove deprecated param movingOnWindowChange. 22 | 23 | 24 | ## [1.5.2+3] 25 | Format. 26 | 27 | 28 | ## [1.5.2+2] 29 | Fix bug. 30 | 31 | 32 | ## [1.5.2+1] 33 | * Ability to set `ignoring` parameter for `IgnorePointer` widget (contributed by @agordn52). 34 | * Permanent toast, when set [duration] to Duration.zero, toast won't dismiss automatically. 35 | 36 | 37 | ## [1.5.1+1] 38 | Change [StyledToast] from StatelessWidget to StatefulWidget. 39 | Add [onInitState] to StyledToast and StyledToastTheme. 40 | 41 | 42 | ## [1.5.0+2] 43 | Delete deprecated parameter [movingOnWindowChange] usage. 44 | 45 | 46 | ## [1.5.0+1] 47 | Add parameter isHideKeyboard (default is true), if true, when toast show, keyboard will be hidden. 48 | Add parameter animationBuilder, builder method for custom animation 49 | Add parameter reverseAnimBuilder, builder method for custom reverse animation 50 | Add parameter onInitState, toast widget initState callback. 51 | 52 | 53 | ## [1.4.0+1] 54 | Improve documentation. 55 | 56 | 57 | ## [1.4.0] 58 | Add fullWidth parameter, controls whether the width of default toast widget is full screen. 59 | Code optimization. 60 | Fix the bug when dismiss toast. 61 | 62 | 63 | ## [1.3.2] 64 | Fix unused import. 65 | 66 | 67 | ## [1.3.1] 68 | Add locale as required parameter in StyledToast. 69 | Fix TextFields context menu exception with Flutter 1.17.0. 70 | 71 | 72 | ## [1.3.0] 73 | Add toast position: topLeft, topRight, centerLeft, centerRight, bottomLeft, bottomRight. 74 | Add custom size transition to support alignment in size transition animation. Fix size transition bug. Modify example. 75 | 76 | 77 | ## [1.2.1] 78 | 79 | Add start offset, reverse end offset in StyledToast. 80 | 81 | 82 | ## [1.2.0] 83 | 84 | Add axis, alignment support to rotate and size animation. 85 | Add start offset, end offset, reverse start offset, reverse end offset to slide animation. 86 | 87 | 88 | ## [1.1.0+5] 89 | 90 | Fix bugs. 91 | 92 | 93 | ## [1.1.0+4] 94 | 95 | Modify README. 96 | 97 | 98 | ## [1.1.0+3] 99 | 100 | Fix bugs. 101 | 102 | 103 | ## [1.1.0] 104 | 105 | Adding size animation sizeFade animation, fix bugs. 106 | 107 | 108 | ## [1.0.0] 109 | 110 | First release version 111 | features: showToast showToastWidget toast animation and reverse animation. 112 | 113 | 114 | ## [0.0.1] 115 | 116 | initial project 117 | 118 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_styled_toast 2 | 3 | A Styled Toast Flutter package. 4 | You can highly customize toast ever. 5 | Beautify toast with a series of animations and make toast more beautiful. 6 | 7 | ## demo 8 | 9 | 10 | 11 | ## Null safety 12 | ```yaml 13 | dependencies: 14 | flutter_styled_toast: ^2.2.1 15 | ``` 16 | 17 | ## Getting Started 18 | 19 | ```yaml 20 | dependencies: 21 | flutter_styled_toast: ^1.5.2+3 22 | ``` 23 | 24 | ```dart 25 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 26 | ``` 27 | 28 | ```dart 29 | //Simple to use, no global configuration 30 | showToast("hello styled toast",context:context); 31 | 32 | //Customize toast content widget, no global configuration 33 | showToastWidget(Text('hello styled toast'),context:context); 34 | ``` 35 | 36 | ```dart 37 | //Interactive toast, set [isIgnoring] false. 38 | showToastWidget( 39 | Container( 40 | padding: EdgeInsets.symmetric(horizontal: 18.0), 41 | margin: EdgeInsets.symmetric(horizontal: 50.0), 42 | decoration: ShapeDecoration( 43 | shape: RoundedRectangleBorder( 44 | borderRadius: BorderRadius.circular(5.0), 45 | ), 46 | color: Colors.green[600], 47 | ), 48 | child: Row( 49 | children: [ 50 | Text( 51 | 'Jump to new page', 52 | style: TextStyle( 53 | color: Colors.white, 54 | ), 55 | ), 56 | IconButton( 57 | onPressed: () { 58 | ToastManager().dismissAll(showAnim: true); 59 | Navigator.push(context, 60 | MaterialPageRoute(builder: (context) { 61 | return SecondPage(); 62 | })); 63 | }, 64 | icon: Icon( 65 | Icons.add_circle_outline_outlined, 66 | color: Colors.white, 67 | ), 68 | ), 69 | ], 70 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 71 | ), 72 | ), 73 | context: context, 74 | isIgnoring: false, 75 | duration: Duration.zero, 76 | ); 77 | ``` 78 | 79 | ```dart 80 | //Set an animation 81 | showToast('This is normal toast with animation', 82 | context: context, 83 | animation: StyledToastAnimation.scale, 84 | ); 85 | 86 | ///Set both animation and reverse animation, 87 | ///combination different animation and reverse animation to achieve amazing effect. 88 | showToast('This is normal toast with animation', 89 | context: context, 90 | animation: StyledToastAnimation.scale, 91 | reverseAnimation: StyledToastAnimation.fade, 92 | position: StyledToastPosition.center, 93 | animDuration: Duration(seconds: 1), 94 | duration: Duration(seconds: 4), 95 | curve: Curves.elasticOut, 96 | reverseCurve: Curves.linear, 97 | ); 98 | 99 | ```dart 100 | 101 | 102 | ```dart 103 | ///Custom animation and custom reverse animation, 104 | ///combination different animation and reverse animation to achieve amazing effect. 105 | 106 | AnimationController mController; 107 | AnimationController mReverseController; 108 | 109 | @override 110 | void initState() { 111 | super.initState(); 112 | mController = 113 | AnimationController(vsync: this, duration: Duration(milliseconds: 200)); 114 | mReverseController = 115 | AnimationController(vsync: this, duration: Duration(milliseconds: 200)); 116 | } 117 | 118 | showToast('This is normal toast with custom animation', 119 | context: context, 120 | position: StyledToastPosition.bottom, 121 | animDuration: Duration(seconds: 1), 122 | duration: Duration(seconds: 4), 123 | animationBuilder: ( 124 | BuildContext context, 125 | AnimationController controller, 126 | Duration duration, 127 | Widget child, 128 | ) { 129 | return SlideTransition( 130 | position: getAnimation( 131 | Offset(0.0, 3.0), Offset(0, 0), controller, 132 | curve: Curves.bounceInOut), 133 | child: child, 134 | ); 135 | }, 136 | reverseAnimBuilder: ( 137 | BuildContext context, 138 | AnimationController controller, 139 | Duration duration, 140 | Widget child, 141 | ) { 142 | return SlideTransition( 143 | position: getAnimation( 144 | Offset(0.0, 0.0), Offset(-3.0, 0), controller, 145 | curve: Curves.bounceInOut), 146 | child: child, 147 | ); 148 | }, 149 | ); 150 | 151 | ```dart 152 | 153 | 154 | ```dart 155 | ///Custom animation, custom reverse animation and custom animation controller 156 | showToast('This is normal toast with custom animation and controller', 157 | context: context, 158 | position: StyledToastPosition.bottom, 159 | animDuration: Duration(seconds: 1), 160 | duration: Duration(seconds: 4), 161 | onInitState:(Duration toastDuration, Duration animDuration) async { 162 | try { 163 | await mController.forward().orCancel; 164 | Future.delayed(toastDuration - animDuration, () async { 165 | await mReverseController.forward().orCancel; 166 | mController.reset(); 167 | mReverseController.reset(); 168 | }); 169 | } on TickerCanceled {} 170 | }, 171 | animationBuilder: ( 172 | BuildContext context, 173 | AnimationController controller, 174 | Duration duration, 175 | Widget child, 176 | ) { 177 | return SlideTransition( 178 | position: getAnimation( 179 | Offset(0.0, 3.0), Offset(0, 0), controller, 180 | curve: Curves.bounceInOut), 181 | child: child, 182 | ); 183 | }, 184 | reverseAnimBuilder: ( 185 | BuildContext context, 186 | AnimationController controller, 187 | Duration duration, 188 | Widget child, 189 | ) { 190 | return SlideTransition( 191 | position: getAnimation( 192 | Offset(0.0, 0.0), Offset(-3.0, 0), controller, 193 | curve: Curves.bounceInOut), 194 | child: child, 195 | ); 196 | }, 197 | ); 198 | 199 | ```dart 200 | 201 | 202 | 203 | Simple global configuration, wrap you app with StyledToast. 204 | ```dart 205 | StyledToast( 206 | locale: const Locale('en', 'US'), 207 | child: MaterialApp( 208 | title: appTitle, 209 | showPerformanceOverlay: showPerformance, 210 | home: LayoutBuilder( 211 | builder: (BuildContext context, BoxConstraints constraints) { 212 | return MyHomePage( 213 | title: appTitle, 214 | onSetting: onSettingCallback, 215 | ); 216 | }, 217 | ), 218 | ), 219 | ); 220 | ``` 221 | 222 | Highly Customizable global configuration 223 | ```dart 224 | StyledToast( 225 | locale: const Locale('en', 'US'), //You have to set this parameters to your locale 226 | textStyle: TextStyle(fontSize: 16.0, color: Colors.white), //Default text style of toast 227 | backgroundColor: Color(0x99000000), //Background color of toast 228 | borderRadius: BorderRadius.circular(5.0), //Border radius of toast 229 | textPadding: EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0),//The padding of toast text 230 | toastPositions: StyledToastPosition.bottom, //The position of toast 231 | toastAnimation: StyledToastAnimation.fade, //The animation type of toast 232 | reverseAnimation: StyledToastAnimation.fade, //The reverse animation of toast (display When dismiss toast) 233 | curve: Curves.fastOutSlowIn, //The curve of animation 234 | reverseCurve: Curves.fastLinearToSlowEaseIn, //The curve of reverse animation 235 | duration: Duration(seconds: 4), //The duration of toast showing, when set [duration] to Duration.zero, toast won't dismiss automatically. 236 | animDuration: Duration(seconds: 1), //The duration of animation(including reverse) of toast 237 | dismissOtherOnShow: true, //When we show a toast and other toast is showing, dismiss any other showing toast before. 238 | movingOnWindowChange: true, //When the window configuration changes, move the toast. 239 | fullWidth: false, //Whether the toast is full screen (subtract the horizontal margin) 240 | isHideKeyboard: false, //Is hide keyboard when toast show 241 | isIgnoring: true, //Is the input ignored for the toast 242 | animationBuilder: (BuildContext context,AnimationController controller,Duration duration,Widget child,){ // Builder method for custom animation 243 | return SlideTransition( 244 | position: getAnimation(Offset(0.0, 3.0),Offset(0,0), controller,curve: Curves.bounceInOut), 245 | child: child, 246 | ); 247 | }, 248 | reverseAnimBuilder: (BuildContext context,AnimationController controller,Duration duration,Widget child,){ // Builder method for custom reverse animation 249 | return SlideTransition( 250 | position: getAnimation(Offset(0.0, 0.0),Offset(-3.0,0), controller,curve: Curves.bounceInOut), 251 | child: child, 252 | ); 253 | }, 254 | child: MaterialApp( 255 | title: appTitle, 256 | showPerformanceOverlay: showPerformance, 257 | home: LayoutBuilder( 258 | builder: (BuildContext context, BoxConstraints constraints) { 259 | return MyHomePage( 260 | title: appTitle, 261 | onSetting: onSettingCallback, 262 | ); 263 | }, 264 | ), 265 | ), 266 | ); 267 | ```dart 268 | 269 | ```dart 270 | //After global configuration, use in a single line. 271 | showToast("hello styled toast"); 272 | 273 | //After global configuration, Customize toast content widget 274 | showToastWidget(Text('hello styled toast')); 275 | ``` 276 | 277 | ## 🚀 Roadmap 278 | 279 | 280 | 281 | 287 | 293 | 299 | 300 | 301 | 307 | 313 | 319 | 320 | 321 | 327 | 333 | 339 | 340 | 341 | 347 | 353 | 359 | 360 | 361 | 367 | 373 | 379 | 380 |
282 | 283 |
284 | DefaultToastWidget 285 |
286 |
288 | 289 |
290 | FadeAnim 291 |
292 |
294 | 295 |
296 | SlideFromTopAnim 297 |
298 |
302 | 303 |
304 | SlideFromBottomAnim 305 |
306 |
308 | 309 |
310 | SlideFromLeftAnim 311 |
312 |
314 | 315 |
316 | SlideFromRightAnim 317 |
318 |
322 | 323 |
324 | ScaleAnim 325 |
326 |
328 | 329 |
330 | FadeScaleAnim 331 |
332 |
334 | 335 |
336 | RotateAnim 337 |
338 |
342 | 343 |
344 | FadeRotateAnim 345 |
346 |
348 | 349 |
350 | ScaleRotateAnim 351 |
352 |
354 | 355 |
356 | OnDismiss 357 |
358 |
362 | 363 |
364 | CustomToastWidget 365 |
366 |
368 | 369 |
370 | CustomFailToastWidget 371 |
372 |
374 | 375 |
376 | CustomSuccessToastWidget 377 |
378 |
381 | 382 | 383 | ### StyledToast param 384 | 385 | property | description 386 | ---------------------|---------------------------- 387 | locale | Locale (Not Null)(required You have to set this parameters to your locale) 388 | child | Widget (Not Null)(required) 389 | textAlign | TextAlign (default TextAlign.center) 390 | textDirection | TextDirection (default TextDirection.ltr) 391 | borderRadius | BorderRadius (BorderRadius.circular(5.0)) 392 | backgroundColor | Color (default Color(0x99000000)) 393 | textPadding | EdgeInsetsGeometry (default EdgeInsets.symmetric(horizontal: 17.0,vertical: 8.0)) 394 | toastHorizontalMargin| double (default 50.0) 395 | textStyle | TextStyle (default TextStyle(fontSize: 16.0,fontWeight: FontWeight.normal,color: Colors.white)) 396 | shapeBorder | ShapeBorder (default RoundedRectangleBorder(borderRadius: borderRadius)) 397 | duration | Duration (default 2.3s)(When set [duration] to Duration.zero, toast won't dismiss automatically) 398 | animDuration | Duration (default 400 milliseconds, animDuration * 2 <= duration, conditions must be met for toast to display properly) 399 | toastPositions | StyledToastPosition (default StyledToastPosition.bottom) 400 | toastAnimation | StyledToastAnimation (default StyledToastAnimation.fade) 401 | reverseAnimation | StyledToastAnimation 402 | alignment | AlignmentGeometry (default Alignment.center) 403 | axis | Axis (default Axis.vertical) 404 | startOffset | Offset 405 | endOffset | Offset 406 | reverseStartOffset | Offset 407 | reverseEndOffset | Offset 408 | curve | Curve (default Curves.linear) 409 | reverseCurve | Curve (default Curves.linear) 410 | dismissOtherOnShow | bool (default true) 411 | onDismiss | VoidCallback (Invoked when toast dismiss) 412 | fullWidth | bool (default false)(Full width parameter that the width of the screen minus the width of the margin.) 413 | isHideKeyboard | bool (default false)(Is hide keyboard when toast show) 414 | animationBuilder | CustomAnimationBuilder (Builder method for custom animation) 415 | reverseAnimBuilder | CustomAnimationBuilder (Builder method for custom reverse animation) 416 | isIgnoring | bool (default true) 417 | onInitState | OnInitStateCallback (When toast widget [initState], this callback will be called) 418 | 419 | 420 | 421 | ### showToast param 422 | 423 | property | description 424 | ---------------------|---------------------------- 425 | msg | String (Not Null)(required) 426 | context | BuildContext (If you don't wrap app with StyledToast, context is required, otherwise, is not) 427 | duration | Duration (default 2.3s)(When set [duration] to Duration.zero, toast won't dismiss automatically) 428 | animDuration | Duration (default 400 milliseconds, animDuration * 2 <= duration, conditions must be met for toast to display properly) 429 | position | StyledToastPosition (default StyledToastPosition.bottom) 430 | textStyle | TextStyle (default TextStyle(fontSize: 16.0,fontWeight: FontWeight.normal,color: Colors.white)) 431 | textPadding | EdgeInsetsGeometry (default EdgeInsets.symmetric(horizontal: 17.0,vertical: 8.0)) 432 | backgroundColor | Color (default Color(0x99000000)) 433 | borderRadius | BorderRadius (BorderRadius.circular(5.0)) 434 | shapeBorder | ShapeBorder (default RoundedRectangleBorder(borderRadius: borderRadius)) 435 | onDismiss | VoidCallback (Invoked when toast dismiss) 436 | textDirection | TextDirection (default TextDirection.ltr) 437 | dismissOtherOnShow | bool (default true) 438 | toastAnimation | StyledToastAnimation (default StyledToastAnimation.fade) 439 | reverseAnimation | StyledToastAnimation 440 | alignment | AlignmentGeometry (default Alignment.center) 441 | axis | Axis (default Axis.vertical) 442 | startOffset | Offset 443 | endOffset | Offset 444 | reverseStartOffset | Offset 445 | reverseEndOffset | Offset 446 | textAlign | TextAlign (default TextAlign.center) 447 | curve | Curve (default Curves.linear) 448 | reverseCurve | Curve (default Curves.linear) 449 | fullWidth | bool (default false)(Full width parameter that the width of the screen minus the width of the margin) 450 | isHideKeyboard | bool (default false)(Is hide keyboard when toast show) 451 | animationBuilder | CustomAnimationBuilder (Builder method for custom animation) 452 | reverseAnimBuilder | CustomAnimationBuilder (Builder method for custom reverse animation) 453 | isIgnoring | bool (default true)(Is the input ignored for the toast) 454 | onInitState | OnInitStateCallback (When toast widget [initState], this callback will be called) 455 | 456 | 457 | 458 | ### showToastWidget param 459 | 460 | property | description 461 | ---------------------|---------------------------- 462 | widget | Widget (Not Null)(required) 463 | context | BuildContext (If you don't wrap app with StyledToast, context is required, otherwise, is not) 464 | duration | Duration (default 2.3s)(When set [duration] to Duration.zero, toast won't dismiss automatically) 465 | animDuration | Duration (default 400 milliseconds, animDuration * 2 <= duration, conditions must be met for toast to display properly) 466 | onDismiss | VoidCallback (Invoked when toast dismiss) 467 | dismissOtherOnShow | bool (default true) 468 | textDirection | TextDirection (default TextDirection.ltr) 469 | position | StyledToastPosition (default ) 470 | animation | StyledToastAnimation (default StyledToastAnimation.fade) 471 | reverseAnimation | StyledToastAnimation 472 | alignment | AlignmentGeometry (default Alignment.center) 473 | axis | Axis (default Axis.vertical) 474 | startOffset | Offset 475 | endOffset | Offset 476 | reverseStartOffset | Offset 477 | reverseEndOffset | Offset 478 | curve | Curve (default Curves.linear) 479 | reverseCurve | Curve (default Curves.linear) 480 | isHideKeyboard | bool (default false)(Is hide keyboard when toast show) 481 | animationBuilder | CustomAnimationBuilder (Builder method for custom animation) 482 | reverseAnimBuilder | CustomAnimationBuilder (Builder method for custom reverse animation) 483 | isIgnoring | bool (default true )(Is the input ignored for the toast) 484 | onInitState | OnInitStateCallback (When toast widget [initState], this callback will be called) 485 | 486 | 487 | ## Example 488 | [example](https://github.com/JackJonson/flutter_styled_toast/blob/master/example/lib/main.dart) 489 | 490 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | linter: 4 | rules: 5 | avoid_print: true 6 | annotate_overrides: true 7 | hash_and_equals: true 8 | prefer_is_not_empty: true 9 | prefer_relative_imports: true 10 | prefer_single_quotes: true 11 | sort_child_properties_last: false 12 | use_build_context_synchronously: false 13 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | pubspec.lock 30 | 31 | # Android related 32 | **/android/**/gradle-wrapper.jar 33 | **/android/.gradle 34 | **/android/captures/ 35 | **/android/gradlew 36 | **/android/gradlew.bat 37 | **/android/local.properties 38 | **/android/**/GeneratedPluginRegistrant.java 39 | 40 | # iOS/XCode related 41 | **/ios/**/*.mode1v3 42 | **/ios/**/*.mode2v3 43 | **/ios/**/*.moved-aside 44 | **/ios/**/*.pbxuser 45 | **/ios/**/*.perspectivev3 46 | **/ios/**/*sync/ 47 | **/ios/**/.sconsign.dblite 48 | **/ios/**/.tags* 49 | **/ios/**/.vagrant/ 50 | **/ios/**/DerivedData/ 51 | **/ios/**/Icon? 52 | **/ios/**/Pods/ 53 | **/ios/**/.symlinks/ 54 | **/ios/**/profile 55 | **/ios/**/xcuserdata 56 | **/ios/.generated/ 57 | **/ios/Flutter/App.framework 58 | **/ios/Flutter/Flutter.framework 59 | **/ios/Flutter/Generated.xcconfig 60 | **/ios/Flutter/app.flx 61 | **/ios/Flutter/app.zip 62 | **/ios/Flutter/flutter_assets/ 63 | **/ios/ServiceDefinitions.json 64 | **/ios/Runner/GeneratedPluginRegistrant.* 65 | **/ios/Flutter/flutter_export_environment.sh 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter application. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.jackjonson.example" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 14 | 17 | 18 | 25 | 29 | 30 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/jackjonson/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.jackjonson.example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/normal_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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.4.3' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/assets/ic_error.json: -------------------------------------------------------------------------------- 1 | {"v":"5.3.4","fr":24,"ip":0,"op":40,"w":89,"h":89,"nm":"Rejected 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Top-left-line Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[44.271,44.271,0],"ix":2},"a":{"a":0,"k":[44.271,44.271,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-9.013,-9.012],[9.013,9.012]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[35.258,35.258],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":12}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[55]},{"t":24}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8674,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Top-right-line Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[44.271,44.271,0],"ix":2},"a":{"a":0,"k":[44.271,44.271,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[9.017,-9.017],[-9.017,9.016]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[53.288,35.254],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":12}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[55]},{"t":24}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8674,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Bottom-left-line Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[44.271,44.271,0],"ix":2},"a":{"a":0,"k":[44.271,44.271,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-9.01,9.011],[9.01,-9.011]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[35.261,53.282],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":12}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[55]},{"t":24}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8674,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Bottom-right-line Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[44.271,44.271,0],"ix":2},"a":{"a":0,"k":[44.271,44.271,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[9.014,9.014],[-9.014,-9.014]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[53.285,53.285],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":12}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[55]},{"t":24}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8674,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Circle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[44.271,44.271,0],"ix":2},"a":{"a":0,"k":[44.271,44.271,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-15.18],[15.179,0],[0,15.18],[-15.18,0]],"o":[[0,15.18],[-15.18,0],[0,-15.18],[15.179,0]],"v":[[27.485,-0.001],[0,27.484],[-27.485,-0.001],[0,-27.484]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.922000002394,0.13300000359,0.152999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[44.272,44.272],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":8674,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Background Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[60],"e":[100]},{"t":24}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[44.271,44.271,0],"ix":2},"a":{"a":0,"k":[44.271,44.271,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[13.79,13.79,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-24.45],[24.45,0],[0,24.451],[-24.451,0]],"o":[[0,24.451],[-24.451,0],[0,-24.45],[24.45,0]],"v":[[44.271,0],[0,44.271],[-44.272,0],[0,-44.271]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.885999971278,0.889999988032,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[44.271,44.271],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":8674,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /example/assets/ic_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/example/assets/ic_fail.png -------------------------------------------------------------------------------- /example/assets/ic_success.json: -------------------------------------------------------------------------------- 1 | {"v":"4.10.1","fr":48,"ip":0,"op":48,"w":80,"h":80,"nm":"引导 对勾 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"对勾","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38.875,36.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-25.236,-8.222],[-1.702,13.989],[20.459,-8.403]],"c":false},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.735],"y":[1]},"o":{"x":[0.254],"y":[0.884]},"n":["0p735_1_0p254_0p884"],"t":24,"s":[2],"e":[95]},{"t":36}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.46],"y":[0.944]},"o":{"x":[0.66],"y":[0.047]},"n":["0p46_0p944_0p66_0p047"],"t":24,"s":[0],"e":[25]},{"t":36}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":24,"s":[0],"e":[16]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":36,"s":[16],"e":[0]},{"t":38}],"ix":3},"m":1,"ix":2,"nm":"修剪路径 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"形状 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":24,"op":480,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"外圈","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.425],"y":[0.998]},"o":{"x":[0.525],"y":[0.035]},"n":["0p425_0p998_0p525_0p035"],"t":0,"s":[80],"e":[22]},{"t":24}],"ix":10},"p":{"a":0,"k":[40.5,40,0],"ix":2},"a":{"a":0,"k":[1.201,3.701,0],"ix":1},"s":{"a":0,"k":[106.434,106.434,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-15.023,0],[0,-15.023],[15.023,0],[0,15.023]],"o":[[15.023,0],[0,15.023],[-15.023,0],[0,-15.023]],"v":[[0,-27.201],[27.201,0],[0,27.201],[-27.201,0]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.482],"y":[0.997]},"o":{"x":[0.878],"y":[0]},"n":["0p482_0p997_0p878_0"],"t":0,"s":[100],"e":[0]},{"t":24}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"修剪路径 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1.518,3.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-90,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":480,"st":0,"bm":0}]} -------------------------------------------------------------------------------- /example/assets/ic_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/example/assets/ic_success.png -------------------------------------------------------------------------------- /example/assets/ic_success.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 76318C614C246BF78EBF743C /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D9DE6CBC5FA7B628BF4E8AF3 /* libPods-Runner.a */; }; 13 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 14 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 15 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 16 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 17 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 18 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXCopyFilesBuildPhase section */ 22 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 23 | isa = PBXCopyFilesBuildPhase; 24 | buildActionMask = 2147483647; 25 | dstPath = ""; 26 | dstSubfolderSpec = 10; 27 | files = ( 28 | ); 29 | name = "Embed Frameworks"; 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXCopyFilesBuildPhase section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 36 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 37 | 20B876EBDC1565CE434ACD23 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 38 | 35586AB32020537FE02FAEE7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 39 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | 900C18385D060D7E1C820B2B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 44 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 45 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 46 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 48 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | D9DE6CBC5FA7B628BF4E8AF3 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | 76318C614C246BF78EBF743C /* libPods-Runner.a in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 6BE595D415F53E3709C31368 /* Pods */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 35586AB32020537FE02FAEE7 /* Pods-Runner.debug.xcconfig */, 71 | 900C18385D060D7E1C820B2B /* Pods-Runner.release.xcconfig */, 72 | 20B876EBDC1565CE434ACD23 /* Pods-Runner.profile.xcconfig */, 73 | ); 74 | name = Pods; 75 | path = Pods; 76 | sourceTree = ""; 77 | }; 78 | 6DEA760952FA311CAECBF699 /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | D9DE6CBC5FA7B628BF4E8AF3 /* libPods-Runner.a */, 82 | ); 83 | name = Frameworks; 84 | sourceTree = ""; 85 | }; 86 | 9740EEB11CF90186004384FC /* Flutter */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 90 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 91 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 92 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 93 | ); 94 | name = Flutter; 95 | sourceTree = ""; 96 | }; 97 | 97C146E51CF9000F007C117D = { 98 | isa = PBXGroup; 99 | children = ( 100 | 9740EEB11CF90186004384FC /* Flutter */, 101 | 97C146F01CF9000F007C117D /* Runner */, 102 | 97C146EF1CF9000F007C117D /* Products */, 103 | 6BE595D415F53E3709C31368 /* Pods */, 104 | 6DEA760952FA311CAECBF699 /* Frameworks */, 105 | ); 106 | sourceTree = ""; 107 | }; 108 | 97C146EF1CF9000F007C117D /* Products */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 97C146EE1CF9000F007C117D /* Runner.app */, 112 | ); 113 | name = Products; 114 | sourceTree = ""; 115 | }; 116 | 97C146F01CF9000F007C117D /* Runner */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 120 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 121 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 122 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 123 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 124 | 97C147021CF9000F007C117D /* Info.plist */, 125 | 97C146F11CF9000F007C117D /* Supporting Files */, 126 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 127 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 128 | ); 129 | path = Runner; 130 | sourceTree = ""; 131 | }; 132 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 97C146F21CF9000F007C117D /* main.m */, 136 | ); 137 | name = "Supporting Files"; 138 | sourceTree = ""; 139 | }; 140 | /* End PBXGroup section */ 141 | 142 | /* Begin PBXNativeTarget section */ 143 | 97C146ED1CF9000F007C117D /* Runner */ = { 144 | isa = PBXNativeTarget; 145 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 146 | buildPhases = ( 147 | 9E5D07DAD30B46E615D4DCC2 /* [CP] Check Pods Manifest.lock */, 148 | 9740EEB61CF901F6004384FC /* Run Script */, 149 | 97C146EA1CF9000F007C117D /* Sources */, 150 | 97C146EB1CF9000F007C117D /* Frameworks */, 151 | 97C146EC1CF9000F007C117D /* Resources */, 152 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 153 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 154 | 6B3B89F8A75E3E680A3697A3 /* [CP] Embed Pods Frameworks */, 155 | ); 156 | buildRules = ( 157 | ); 158 | dependencies = ( 159 | ); 160 | name = Runner; 161 | productName = Runner; 162 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 163 | productType = "com.apple.product-type.application"; 164 | }; 165 | /* End PBXNativeTarget section */ 166 | 167 | /* Begin PBXProject section */ 168 | 97C146E61CF9000F007C117D /* Project object */ = { 169 | isa = PBXProject; 170 | attributes = { 171 | LastUpgradeCheck = 0910; 172 | ORGANIZATIONNAME = "The Chromium Authors"; 173 | TargetAttributes = { 174 | 97C146ED1CF9000F007C117D = { 175 | CreatedOnToolsVersion = 7.3.1; 176 | DevelopmentTeam = J3YBGWZ37Y; 177 | }; 178 | }; 179 | }; 180 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 181 | compatibilityVersion = "Xcode 3.2"; 182 | developmentRegion = English; 183 | hasScannedForEncodings = 0; 184 | knownRegions = ( 185 | en, 186 | Base, 187 | ); 188 | mainGroup = 97C146E51CF9000F007C117D; 189 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 190 | projectDirPath = ""; 191 | projectRoot = ""; 192 | targets = ( 193 | 97C146ED1CF9000F007C117D /* Runner */, 194 | ); 195 | }; 196 | /* End PBXProject section */ 197 | 198 | /* Begin PBXResourcesBuildPhase section */ 199 | 97C146EC1CF9000F007C117D /* Resources */ = { 200 | isa = PBXResourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 204 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 205 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 206 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 207 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXResourcesBuildPhase section */ 212 | 213 | /* Begin PBXShellScriptBuildPhase section */ 214 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 215 | isa = PBXShellScriptBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | ); 219 | inputPaths = ( 220 | ); 221 | name = "Thin Binary"; 222 | outputPaths = ( 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | shellPath = /bin/sh; 226 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 227 | }; 228 | 6B3B89F8A75E3E680A3697A3 /* [CP] Embed Pods Frameworks */ = { 229 | isa = PBXShellScriptBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | ); 233 | inputPaths = ( 234 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 235 | "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", 236 | ); 237 | name = "[CP] Embed Pods Frameworks"; 238 | outputPaths = ( 239 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | shellPath = /bin/sh; 243 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 244 | showEnvVarsInLog = 0; 245 | }; 246 | 9740EEB61CF901F6004384FC /* Run Script */ = { 247 | isa = PBXShellScriptBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | ); 251 | inputPaths = ( 252 | ); 253 | name = "Run Script"; 254 | outputPaths = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | shellPath = /bin/sh; 258 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 259 | }; 260 | 9E5D07DAD30B46E615D4DCC2 /* [CP] Check Pods Manifest.lock */ = { 261 | isa = PBXShellScriptBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | ); 265 | inputFileListPaths = ( 266 | ); 267 | inputPaths = ( 268 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 269 | "${PODS_ROOT}/Manifest.lock", 270 | ); 271 | name = "[CP] Check Pods Manifest.lock"; 272 | outputFileListPaths = ( 273 | ); 274 | outputPaths = ( 275 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | shellPath = /bin/sh; 279 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 280 | showEnvVarsInLog = 0; 281 | }; 282 | /* End PBXShellScriptBuildPhase section */ 283 | 284 | /* Begin PBXSourcesBuildPhase section */ 285 | 97C146EA1CF9000F007C117D /* Sources */ = { 286 | isa = PBXSourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 290 | 97C146F31CF9000F007C117D /* main.m in Sources */, 291 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXSourcesBuildPhase section */ 296 | 297 | /* Begin PBXVariantGroup section */ 298 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 299 | isa = PBXVariantGroup; 300 | children = ( 301 | 97C146FB1CF9000F007C117D /* Base */, 302 | ); 303 | name = Main.storyboard; 304 | sourceTree = ""; 305 | }; 306 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 307 | isa = PBXVariantGroup; 308 | children = ( 309 | 97C147001CF9000F007C117D /* Base */, 310 | ); 311 | name = LaunchScreen.storyboard; 312 | sourceTree = ""; 313 | }; 314 | /* End PBXVariantGroup section */ 315 | 316 | /* Begin XCBuildConfiguration section */ 317 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | ALWAYS_SEARCH_USER_PATHS = NO; 321 | CLANG_ANALYZER_NONNULL = YES; 322 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 323 | CLANG_CXX_LIBRARY = "libc++"; 324 | CLANG_ENABLE_MODULES = YES; 325 | CLANG_ENABLE_OBJC_ARC = YES; 326 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 327 | CLANG_WARN_BOOL_CONVERSION = YES; 328 | CLANG_WARN_COMMA = YES; 329 | CLANG_WARN_CONSTANT_CONVERSION = YES; 330 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 331 | CLANG_WARN_EMPTY_BODY = YES; 332 | CLANG_WARN_ENUM_CONVERSION = YES; 333 | CLANG_WARN_INFINITE_RECURSION = YES; 334 | CLANG_WARN_INT_CONVERSION = YES; 335 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 336 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 337 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 338 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 339 | CLANG_WARN_STRICT_PROTOTYPES = YES; 340 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 341 | CLANG_WARN_UNREACHABLE_CODE = YES; 342 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 343 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 344 | COPY_PHASE_STRIP = NO; 345 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 346 | ENABLE_NS_ASSERTIONS = NO; 347 | ENABLE_STRICT_OBJC_MSGSEND = YES; 348 | GCC_C_LANGUAGE_STANDARD = gnu99; 349 | GCC_NO_COMMON_BLOCKS = YES; 350 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 351 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 352 | GCC_WARN_UNDECLARED_SELECTOR = YES; 353 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 354 | GCC_WARN_UNUSED_FUNCTION = YES; 355 | GCC_WARN_UNUSED_VARIABLE = YES; 356 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 357 | MTL_ENABLE_DEBUG_INFO = NO; 358 | SDKROOT = iphoneos; 359 | TARGETED_DEVICE_FAMILY = "1,2"; 360 | VALIDATE_PRODUCT = YES; 361 | }; 362 | name = Profile; 363 | }; 364 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 365 | isa = XCBuildConfiguration; 366 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 367 | buildSettings = { 368 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 369 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 370 | DEVELOPMENT_TEAM = J3YBGWZ37Y; 371 | ENABLE_BITCODE = NO; 372 | FRAMEWORK_SEARCH_PATHS = ( 373 | "$(inherited)", 374 | "$(PROJECT_DIR)/Flutter", 375 | ); 376 | INFOPLIST_FILE = Runner/Info.plist; 377 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 378 | LIBRARY_SEARCH_PATHS = ( 379 | "$(inherited)", 380 | "$(PROJECT_DIR)/Flutter", 381 | ); 382 | PRODUCT_BUNDLE_IDENTIFIER = com.jackjonson.example; 383 | PRODUCT_NAME = "$(TARGET_NAME)"; 384 | VERSIONING_SYSTEM = "apple-generic"; 385 | }; 386 | name = Profile; 387 | }; 388 | 97C147031CF9000F007C117D /* Debug */ = { 389 | isa = XCBuildConfiguration; 390 | buildSettings = { 391 | ALWAYS_SEARCH_USER_PATHS = NO; 392 | CLANG_ANALYZER_NONNULL = YES; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 398 | CLANG_WARN_BOOL_CONVERSION = YES; 399 | CLANG_WARN_COMMA = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 402 | CLANG_WARN_EMPTY_BODY = YES; 403 | CLANG_WARN_ENUM_CONVERSION = YES; 404 | CLANG_WARN_INFINITE_RECURSION = YES; 405 | CLANG_WARN_INT_CONVERSION = YES; 406 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 407 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 409 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 410 | CLANG_WARN_STRICT_PROTOTYPES = YES; 411 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 412 | CLANG_WARN_UNREACHABLE_CODE = YES; 413 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 414 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 415 | COPY_PHASE_STRIP = NO; 416 | DEBUG_INFORMATION_FORMAT = dwarf; 417 | ENABLE_STRICT_OBJC_MSGSEND = YES; 418 | ENABLE_TESTABILITY = YES; 419 | GCC_C_LANGUAGE_STANDARD = gnu99; 420 | GCC_DYNAMIC_NO_PIC = NO; 421 | GCC_NO_COMMON_BLOCKS = YES; 422 | GCC_OPTIMIZATION_LEVEL = 0; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "DEBUG=1", 425 | "$(inherited)", 426 | ); 427 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 428 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 429 | GCC_WARN_UNDECLARED_SELECTOR = YES; 430 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 431 | GCC_WARN_UNUSED_FUNCTION = YES; 432 | GCC_WARN_UNUSED_VARIABLE = YES; 433 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 434 | MTL_ENABLE_DEBUG_INFO = YES; 435 | ONLY_ACTIVE_ARCH = YES; 436 | SDKROOT = iphoneos; 437 | TARGETED_DEVICE_FAMILY = "1,2"; 438 | }; 439 | name = Debug; 440 | }; 441 | 97C147041CF9000F007C117D /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ALWAYS_SEARCH_USER_PATHS = NO; 445 | CLANG_ANALYZER_NONNULL = YES; 446 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 447 | CLANG_CXX_LIBRARY = "libc++"; 448 | CLANG_ENABLE_MODULES = YES; 449 | CLANG_ENABLE_OBJC_ARC = YES; 450 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 451 | CLANG_WARN_BOOL_CONVERSION = YES; 452 | CLANG_WARN_COMMA = YES; 453 | CLANG_WARN_CONSTANT_CONVERSION = YES; 454 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 455 | CLANG_WARN_EMPTY_BODY = YES; 456 | CLANG_WARN_ENUM_CONVERSION = YES; 457 | CLANG_WARN_INFINITE_RECURSION = YES; 458 | CLANG_WARN_INT_CONVERSION = YES; 459 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 460 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 461 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 462 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 463 | CLANG_WARN_STRICT_PROTOTYPES = YES; 464 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 465 | CLANG_WARN_UNREACHABLE_CODE = YES; 466 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 467 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 468 | COPY_PHASE_STRIP = NO; 469 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 470 | ENABLE_NS_ASSERTIONS = NO; 471 | ENABLE_STRICT_OBJC_MSGSEND = YES; 472 | GCC_C_LANGUAGE_STANDARD = gnu99; 473 | GCC_NO_COMMON_BLOCKS = YES; 474 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 475 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 476 | GCC_WARN_UNDECLARED_SELECTOR = YES; 477 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 478 | GCC_WARN_UNUSED_FUNCTION = YES; 479 | GCC_WARN_UNUSED_VARIABLE = YES; 480 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 481 | MTL_ENABLE_DEBUG_INFO = NO; 482 | SDKROOT = iphoneos; 483 | TARGETED_DEVICE_FAMILY = "1,2"; 484 | VALIDATE_PRODUCT = YES; 485 | }; 486 | name = Release; 487 | }; 488 | 97C147061CF9000F007C117D /* Debug */ = { 489 | isa = XCBuildConfiguration; 490 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 491 | buildSettings = { 492 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 493 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 494 | DEVELOPMENT_TEAM = J3YBGWZ37Y; 495 | ENABLE_BITCODE = NO; 496 | FRAMEWORK_SEARCH_PATHS = ( 497 | "$(inherited)", 498 | "$(PROJECT_DIR)/Flutter", 499 | ); 500 | INFOPLIST_FILE = Runner/Info.plist; 501 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 502 | LIBRARY_SEARCH_PATHS = ( 503 | "$(inherited)", 504 | "$(PROJECT_DIR)/Flutter", 505 | ); 506 | PRODUCT_BUNDLE_IDENTIFIER = com.jackjonson.example; 507 | PRODUCT_NAME = "$(TARGET_NAME)"; 508 | VERSIONING_SYSTEM = "apple-generic"; 509 | }; 510 | name = Debug; 511 | }; 512 | 97C147071CF9000F007C117D /* Release */ = { 513 | isa = XCBuildConfiguration; 514 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 515 | buildSettings = { 516 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 517 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 518 | DEVELOPMENT_TEAM = J3YBGWZ37Y; 519 | ENABLE_BITCODE = NO; 520 | FRAMEWORK_SEARCH_PATHS = ( 521 | "$(inherited)", 522 | "$(PROJECT_DIR)/Flutter", 523 | ); 524 | INFOPLIST_FILE = Runner/Info.plist; 525 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 526 | LIBRARY_SEARCH_PATHS = ( 527 | "$(inherited)", 528 | "$(PROJECT_DIR)/Flutter", 529 | ); 530 | PRODUCT_BUNDLE_IDENTIFIER = com.jackjonson.example; 531 | PRODUCT_NAME = "$(TARGET_NAME)"; 532 | VERSIONING_SYSTEM = "apple-generic"; 533 | }; 534 | name = Release; 535 | }; 536 | /* End XCBuildConfiguration section */ 537 | 538 | /* Begin XCConfigurationList section */ 539 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 97C147031CF9000F007C117D /* Debug */, 543 | 97C147041CF9000F007C117D /* Release */, 544 | 249021D3217E4FDB00AE95B9 /* Profile */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 550 | isa = XCConfigurationList; 551 | buildConfigurations = ( 552 | 97C147061CF9000F007C117D /* Debug */, 553 | 97C147071CF9000F007C117D /* Release */, 554 | 249021D4217E4FDB00AE95B9 /* Profile */, 555 | ); 556 | defaultConfigurationIsVisible = 0; 557 | defaultConfigurationName = Release; 558 | }; 559 | /* End XCConfigurationList section */ 560 | }; 561 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 562 | } 563 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/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/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/lib/blur_transition.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | 6 | /// Blur transition 7 | class BlurTransition extends AnimatedWidget { 8 | /// Creates a blur transition. 9 | const BlurTransition({ 10 | Key? key, 11 | required this.sigma, 12 | this.child, 13 | }) : super(key: key, listenable: sigma); 14 | 15 | final Animation sigma; 16 | 17 | /// The widget below this widget in the tree. 18 | /// 19 | /// {@macro flutter.widgets.child} 20 | final Widget? child; 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return BackdropFilter( 25 | filter: ImageFilter.blur(sigmaX: sigma.value, sigmaY: sigma.value), 26 | child: child, 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example/lib/custom_toast_content_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 3 | 4 | import 'main.dart'; 5 | 6 | /// 7 | ///created time: 2019-06-25 16:42 8 | ///author linzhiliang 9 | ///version 1.5.0 10 | ///since 11 | ///file name: toast_content_widget.dart 12 | ///description: Toast with icon 13 | /// 14 | class IconToastWidget extends StatelessWidget { 15 | final Color? backgroundColor; 16 | final String? message; 17 | final Widget? textWidget; 18 | final double? height; 19 | final double? width; 20 | final String? assetName; 21 | final EdgeInsetsGeometry? padding; 22 | 23 | IconToastWidget({ 24 | super.key, 25 | this.backgroundColor, 26 | this.textWidget, 27 | this.message, 28 | this.height, 29 | this.width, 30 | @required this.assetName, 31 | this.padding, 32 | }); 33 | 34 | factory IconToastWidget.fail({String? msg}) => IconToastWidget( 35 | message: msg, 36 | assetName: 'assets/ic_fail.png', 37 | ); 38 | 39 | factory IconToastWidget.success({String? msg}) => IconToastWidget( 40 | message: msg, 41 | assetName: 'assets/ic_success.png', 42 | ); 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | Widget content = Material( 47 | color: Colors.transparent, 48 | child: Container( 49 | margin: EdgeInsets.symmetric(horizontal: 50.0), 50 | padding: 51 | padding ?? EdgeInsets.symmetric(vertical: 20.0, horizontal: 17.0), 52 | decoration: ShapeDecoration( 53 | color: backgroundColor ?? const Color(0x9F000000), 54 | shape: RoundedRectangleBorder( 55 | borderRadius: BorderRadius.circular(10.0), 56 | ), 57 | ), 58 | child: Wrap( 59 | alignment: WrapAlignment.spaceEvenly, 60 | crossAxisAlignment: WrapCrossAlignment.center, 61 | children: [ 62 | Container( 63 | padding: EdgeInsets.symmetric(horizontal: 5.0), 64 | child: Image.asset( 65 | assetName!, 66 | fit: BoxFit.fill, 67 | width: 30, 68 | height: 30, 69 | ), 70 | ), 71 | Container( 72 | padding: EdgeInsets.symmetric(horizontal: 5.0), 73 | child: textWidget ?? 74 | Text( 75 | message ?? '', 76 | style: TextStyle( 77 | fontSize: 78 | Theme.of(context).textTheme.titleLarge!.fontSize, 79 | color: Colors.white), 80 | softWrap: true, 81 | maxLines: 200, 82 | ), 83 | ), 84 | ], 85 | )), 86 | ); 87 | 88 | return content; 89 | } 90 | } 91 | 92 | /// 93 | ///created time: 2019-06-17 16:22 94 | ///author linzhiliang 95 | ///version 1.5.0 96 | ///since 97 | ///file name: styled_toast.dart 98 | ///description: Banner type toast widget, example of custom toast content widget when you use [showToastWidget] 99 | /// 100 | class BannerToastWidget extends StatelessWidget { 101 | final Color? backgroundColor; 102 | final String? message; 103 | final Widget? textWidget; 104 | final double? offset; 105 | final double? height; 106 | final double? width; 107 | 108 | BannerToastWidget({ 109 | super.key, 110 | this.backgroundColor, 111 | this.textWidget, 112 | this.message, 113 | this.height, 114 | this.width, 115 | final double? offset, 116 | }) : this.offset = (offset == null ? 10.0 : offset); 117 | 118 | factory BannerToastWidget.success( 119 | {String? msg, Widget? text, BuildContext? context}) => 120 | BannerToastWidget( 121 | backgroundColor: context != null 122 | ? Theme.of(context).toggleButtonsTheme.fillColor 123 | : Colors.green, 124 | message: msg, 125 | textWidget: text, 126 | ); 127 | 128 | factory BannerToastWidget.fail( 129 | {String? msg, Widget? text, BuildContext? context}) => 130 | BannerToastWidget( 131 | backgroundColor: context != null 132 | ? Theme.of(context).colorScheme.error 133 | : const Color(0xEFCC2E2E), 134 | message: msg, 135 | textWidget: text, 136 | ); 137 | 138 | @override 139 | Widget build(BuildContext context) { 140 | Widget content = Container( 141 | width: MediaQuery.of(context).size.width, 142 | padding: EdgeInsets.all(17.0), 143 | height: 60.0, 144 | alignment: Alignment.center, 145 | color: backgroundColor ?? Theme.of(context).colorScheme.background, 146 | child: textWidget ?? 147 | Text( 148 | message ?? '', 149 | style: TextStyle( 150 | fontSize: Theme.of(context).textTheme.titleLarge!.fontSize, 151 | color: Colors.white), 152 | ), 153 | ); 154 | 155 | return content; 156 | } 157 | } 158 | 159 | ///Toast with action widget 160 | class ActionToastWidget extends StatelessWidget { 161 | ///Text 162 | final String? text; 163 | 164 | ///Text widget 165 | final Widget? textWidget; 166 | 167 | ///Action widget 168 | final Widget? actionWidget; 169 | 170 | ActionToastWidget({ 171 | this.text, 172 | this.textWidget, 173 | this.actionWidget, 174 | }); 175 | 176 | @override 177 | Widget build(BuildContext context) { 178 | return Container( 179 | padding: EdgeInsets.symmetric(horizontal: 18.0), 180 | margin: EdgeInsets.symmetric(horizontal: 50.0), 181 | decoration: ShapeDecoration( 182 | shape: RoundedRectangleBorder( 183 | borderRadius: BorderRadius.circular(5.0), 184 | ), 185 | color: Colors.green[600], 186 | shadows: [ 187 | const BoxShadow( 188 | offset: Offset.zero, 189 | spreadRadius: 10, 190 | blurRadius: 10, 191 | color: const Color(0x040D0229), 192 | ), 193 | ]), 194 | child: Row( 195 | children: [ 196 | textWidget ?? 197 | Text( 198 | text ?? '', 199 | style: TextStyle( 200 | color: Colors.white, 201 | ), 202 | ), 203 | actionWidget ?? 204 | IconButton( 205 | onPressed: () { 206 | dismissAllToast(showAnim: true); 207 | Navigator.push(context, MaterialPageRoute(builder: (context) { 208 | return SecondPage(); 209 | })); 210 | }, 211 | icon: Icon( 212 | Icons.add_circle_outline_outlined, 213 | color: Colors.white, 214 | ), 215 | ), 216 | ], 217 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 218 | ), 219 | ); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/rendering.dart'; 3 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 4 | 5 | import 'blur_transition.dart'; 6 | import 'custom_toast_content_widget.dart'; 7 | 8 | void main() { 9 | debugPaintSizeEnabled = false; 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatefulWidget { 14 | @override 15 | State createState() { 16 | return _MyAppState(); 17 | } 18 | } 19 | 20 | class _MyAppState extends State { 21 | bool showPerformance = false; 22 | 23 | onSettingCallback() { 24 | setState(() { 25 | showPerformance = !showPerformance; 26 | }); 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | final appTitle = 'Styled Toast Example'; 32 | return StyledToast( 33 | textStyle: TextStyle(fontSize: 16.0, color: Colors.white), 34 | backgroundColor: Color(0x99000000), 35 | borderRadius: BorderRadius.circular(5.0), 36 | textPadding: EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0), 37 | toastAnimation: StyledToastAnimation.size, 38 | reverseAnimation: StyledToastAnimation.size, 39 | startOffset: Offset(0.0, -1.0), 40 | reverseEndOffset: Offset(0.0, -1.0), 41 | duration: Duration(seconds: 4), 42 | animDuration: Duration(seconds: 1), 43 | alignment: Alignment.center, 44 | toastPositions: StyledToastPosition.center, 45 | curve: Curves.fastOutSlowIn, 46 | reverseCurve: Curves.fastOutSlowIn, 47 | dismissOtherOnShow: true, 48 | locale: const Locale('en', 'US'), 49 | fullWidth: false, 50 | isHideKeyboard: false, 51 | isIgnoring: true, 52 | child: MaterialApp( 53 | title: appTitle, 54 | showPerformanceOverlay: showPerformance, 55 | home: LayoutBuilder( 56 | builder: (BuildContext context, BoxConstraints constraints) { 57 | return MyHomePage( 58 | title: appTitle, 59 | onSetting: onSettingCallback, 60 | ); 61 | }, 62 | ), 63 | ), 64 | ); 65 | } 66 | } 67 | 68 | // The StatefulWidget's job is to take in some data and create a State class. 69 | // In this case, the Widget takes a title, and creates a _MyHomePageState. 70 | class MyHomePage extends StatefulWidget { 71 | final String? title; 72 | 73 | final VoidCallback? onSetting; 74 | 75 | MyHomePage({Key? key, this.title, this.onSetting}) : super(key: key); 76 | 77 | @override 78 | _MyHomePageState createState() => _MyHomePageState(); 79 | } 80 | 81 | // The State class is responsible for two things: holding some data you can 82 | // update and building the UI using that data. 83 | class _MyHomePageState extends State 84 | with TickerProviderStateMixin { 85 | // Whether the green box should be visible or invisible 86 | 87 | String dismissRemind = ''; 88 | 89 | TextEditingController controller = TextEditingController(); 90 | 91 | late AnimationController mController; 92 | 93 | late AnimationController mReverseController; 94 | 95 | @override 96 | void initState() { 97 | super.initState(); 98 | mController = 99 | AnimationController(vsync: this, duration: Duration(milliseconds: 200)); 100 | mReverseController = 101 | AnimationController(vsync: this, duration: Duration(milliseconds: 200)); 102 | } 103 | 104 | @override 105 | Widget build(BuildContext context) { 106 | return Scaffold( 107 | appBar: AppBar( 108 | title: Text(widget.title ?? ''), 109 | actions: [ 110 | IconButton( 111 | icon: Icon(Icons.settings), 112 | onPressed: () { 113 | widget.onSetting?.call(); 114 | }, 115 | ) 116 | ], 117 | ), 118 | body: Center( 119 | child: ListView( 120 | padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 20.0), 121 | children: [ 122 | TextField( 123 | controller: TextEditingController(), 124 | ), 125 | Container( 126 | margin: EdgeInsets.only(bottom: 10.0), 127 | padding: EdgeInsets.only(left: 15.0), 128 | height: 35.0, 129 | alignment: Alignment.centerLeft, 130 | child: Text('Normal Toast'), 131 | color: const Color(0xFFDDDDDD), 132 | ), 133 | 134 | ListTile( 135 | title: Text('Normal toast'), 136 | onTap: () { 137 | showToast('This is toast', 138 | context: context, 139 | axis: Axis.horizontal, 140 | alignment: Alignment.center, 141 | position: StyledToastPosition.bottom); 142 | }, 143 | ), 144 | Divider( 145 | height: 0.5, 146 | ), 147 | ListTile( 148 | title: Text('Permanent toast'), 149 | onTap: () { 150 | showToast( 151 | 'This is a permanent toast', 152 | context: context, 153 | duration: Duration.zero, 154 | ); 155 | }, 156 | ), 157 | Divider( 158 | height: 0.5, 159 | ), 160 | ListTile( 161 | title: Text('Normal toast full width'), 162 | onTap: () { 163 | showToast( 164 | 'This is normal', 165 | context: context, 166 | axis: Axis.horizontal, 167 | alignment: Alignment.center, 168 | position: StyledToastPosition.bottom, 169 | borderRadius: BorderRadius.zero, 170 | toastHorizontalMargin: 0, 171 | fullWidth: true, 172 | ); 173 | }, 174 | ), 175 | Divider( 176 | height: 0.5, 177 | ), 178 | ListTile( 179 | title: Text('Normal toast full width with horizontal margin'), 180 | onTap: () { 181 | showToast( 182 | 'This is normal', 183 | context: context, 184 | axis: Axis.horizontal, 185 | alignment: Alignment.center, 186 | position: StyledToastPosition.bottom, 187 | toastHorizontalMargin: 20, 188 | fullWidth: true, 189 | ); 190 | }, 191 | ), 192 | Divider( 193 | height: 0.5, 194 | ), 195 | ListTile( 196 | title: Text( 197 | 'Normal toast(custom borderRadius textStyle etc)', 198 | ), 199 | onTap: () { 200 | showToast('This is normal toast', 201 | context: context, 202 | textStyle: TextStyle(fontSize: 20.0, color: Colors.red), 203 | backgroundColor: Colors.yellow, 204 | textPadding: 205 | EdgeInsets.symmetric(vertical: 20.0, horizontal: 30.0), 206 | borderRadius: BorderRadius.vertical( 207 | top: Radius.elliptical(10.0, 20.0), 208 | bottom: Radius.elliptical(10.0, 20.0)), 209 | textAlign: TextAlign.justify, 210 | textDirection: TextDirection.rtl); 211 | }, 212 | ), 213 | Divider( 214 | height: 0.5, 215 | ), 216 | ListTile( 217 | title: Text( 218 | 'Normal toast(position)', 219 | ), 220 | onTap: () { 221 | showToast('This is normal toast', 222 | context: context, 223 | alignment: Alignment.center, 224 | position: StyledToastPosition( 225 | align: Alignment.bottomCenter, offset: 20.0)); 226 | }, 227 | ), 228 | Divider( 229 | height: 0.5, 230 | ), 231 | ListTile( 232 | title: Text( 233 | 'Normal toast(custom position)', 234 | ), 235 | onTap: () { 236 | showToast('This is toast', 237 | context: context, 238 | toastHorizontalMargin: 10.0, 239 | position: StyledToastPosition( 240 | align: Alignment.topLeft, offset: 20.0)); 241 | }, 242 | ), 243 | Divider( 244 | height: 0.5, 245 | ), 246 | ListTile( 247 | title: Text( 248 | 'Normal toast(fade anim)', 249 | ), 250 | onTap: () { 251 | showToast('This is normal toast with fade animation', 252 | context: context, 253 | animation: StyledToastAnimation.fade, 254 | curve: Curves.linear, 255 | reverseCurve: Curves.linear); 256 | }, 257 | ), 258 | Divider( 259 | height: 0.5, 260 | ), 261 | ListTile( 262 | title: Text( 263 | 'Normal toast(slideFromTop anim)', 264 | ), 265 | onTap: () { 266 | showToast('This is normal toast with animation', 267 | context: context, 268 | animation: StyledToastAnimation.slideFromTop, 269 | reverseAnimation: StyledToastAnimation.slideToTop, 270 | position: StyledToastPosition.top, 271 | startOffset: Offset(0.0, -3.0), 272 | reverseEndOffset: Offset(0.0, -3.0), 273 | duration: Duration(seconds: 4), 274 | //Animation duration animDuration * 2 <= duration 275 | animDuration: Duration(seconds: 1), 276 | curve: Curves.elasticOut, 277 | reverseCurve: Curves.fastOutSlowIn); 278 | }, 279 | ), 280 | Divider( 281 | height: 0.5, 282 | ), 283 | ListTile( 284 | title: Text( 285 | 'Normal toast(slideFromTopFade anim)', 286 | ), 287 | onTap: () { 288 | showToast('This is normal toast with animation', 289 | context: context, 290 | animation: StyledToastAnimation.slideFromTopFade, 291 | reverseAnimation: StyledToastAnimation.slideToTopFade, 292 | position: StyledToastPosition( 293 | align: Alignment.topCenter, offset: 0.0), 294 | startOffset: Offset(0.0, -3.0), 295 | reverseEndOffset: Offset(0.0, -3.0), 296 | duration: Duration(seconds: 4), 297 | //Animation duration animDuration * 2 <= duration 298 | animDuration: Duration(seconds: 1), 299 | curve: Curves.fastLinearToSlowEaseIn, 300 | reverseCurve: Curves.fastOutSlowIn); 301 | }, 302 | ), 303 | Divider( 304 | height: 0.5, 305 | ), 306 | ListTile( 307 | title: Text( 308 | 'Normal toast(slideFromBottom anim)', 309 | ), 310 | onTap: () { 311 | showToast('This is normal toast with animation', 312 | context: context, 313 | animation: StyledToastAnimation.slideFromBottom, 314 | reverseAnimation: StyledToastAnimation.slideToBottom, 315 | startOffset: Offset(0.0, 3.0), 316 | reverseEndOffset: Offset(0.0, 3.0), 317 | position: StyledToastPosition.bottom, 318 | duration: Duration(seconds: 4), 319 | //Animation duration animDuration * 2 <= duration 320 | animDuration: Duration(seconds: 1), 321 | curve: Curves.elasticOut, 322 | reverseCurve: Curves.fastOutSlowIn); 323 | }, 324 | ), 325 | Divider( 326 | height: 0.5, 327 | ), 328 | ListTile( 329 | title: Text( 330 | 'Normal toast(slideFromBottomFade anim)', 331 | ), 332 | onTap: () { 333 | showToast('This is normal toast with animation', 334 | context: context, 335 | animation: StyledToastAnimation.slideFromBottomFade, 336 | reverseAnimation: StyledToastAnimation.slideToBottomFade, 337 | startOffset: Offset(0.0, 3.0), 338 | reverseEndOffset: Offset(0.0, 3.0), 339 | position: StyledToastPosition( 340 | align: Alignment.bottomCenter, offset: 0.0), 341 | duration: Duration(seconds: 4), 342 | //Animation duration animDuration * 2 <= duration 343 | animDuration: Duration(milliseconds: 400), 344 | curve: Curves.linearToEaseOut, 345 | reverseCurve: Curves.fastOutSlowIn); 346 | }, 347 | ), 348 | Divider( 349 | height: 0.5, 350 | ), 351 | ListTile( 352 | title: Text( 353 | 'normal toast(slideFromLeft anim)', 354 | ), 355 | onTap: () { 356 | showToast('This is normal toast with animation', 357 | context: context, 358 | animation: StyledToastAnimation.slideFromLeft, 359 | reverseAnimation: StyledToastAnimation.slideToTop, 360 | position: StyledToastPosition.top, 361 | startOffset: Offset(-1.0, 0.0), 362 | reverseEndOffset: Offset(-1.0, 0.0), 363 | //Toast duration animDuration * 2 <= duration 364 | duration: Duration(seconds: 4), 365 | //Animation duration animDuration * 2 <= duration 366 | animDuration: Duration(seconds: 1), 367 | curve: Curves.elasticOut, 368 | reverseCurve: Curves.fastOutSlowIn); 369 | }, 370 | ), 371 | Divider( 372 | height: 0.5, 373 | ), 374 | ListTile( 375 | title: Text( 376 | 'normal toast(slideFromLeftFade anim)', 377 | ), 378 | onTap: () { 379 | showToast('This is normal toast with animation', 380 | context: context, 381 | animation: StyledToastAnimation.slideFromLeftFade, 382 | reverseAnimation: StyledToastAnimation.slideToTopFade, 383 | toastHorizontalMargin: 0.0, 384 | position: StyledToastPosition( 385 | align: Alignment.topLeft, offset: 20.0), 386 | startOffset: Offset(-1.0, 0.0), 387 | reverseEndOffset: Offset(-1.0, 0.0), 388 | //Toast duration animDuration * 2 <= duration 389 | duration: Duration(seconds: 4), 390 | //Animation duration animDuration * 2 <= duration 391 | animDuration: Duration(seconds: 1), 392 | curve: Curves.linearToEaseOut, 393 | reverseCurve: Curves.fastOutSlowIn); 394 | }, 395 | ), 396 | Divider( 397 | height: 0.5, 398 | ), 399 | ListTile( 400 | title: Text( 401 | 'Normal toast(slideFromRight anim)', 402 | ), 403 | onTap: () { 404 | showToast('This is normal toast with animation', 405 | context: context, 406 | animation: StyledToastAnimation.slideFromRight, 407 | reverseAnimation: StyledToastAnimation.slideToRight, 408 | position: StyledToastPosition.top, 409 | startOffset: Offset(1.0, 0.0), 410 | reverseEndOffset: Offset(1.0, 0.0), 411 | animDuration: Duration(seconds: 1), 412 | duration: Duration(seconds: 4), 413 | curve: Curves.linearToEaseOut, 414 | reverseCurve: Curves.fastOutSlowIn); 415 | }, 416 | ), 417 | Divider( 418 | height: 0.5, 419 | ), 420 | ListTile( 421 | title: Text( 422 | 'Normal toast(slideFromRightFade anim)', 423 | ), 424 | onTap: () { 425 | showToast('This is normal toast with animation', 426 | context: context, 427 | animation: StyledToastAnimation.slideFromRightFade, 428 | reverseAnimation: StyledToastAnimation.slideToRightFade, 429 | toastHorizontalMargin: 0.0, 430 | position: StyledToastPosition( 431 | align: Alignment.topRight, offset: 20.0), 432 | startOffset: Offset(1.0, 0.0), 433 | reverseEndOffset: Offset(1.0, 0.0), 434 | animDuration: Duration(seconds: 1), 435 | duration: Duration(seconds: 4), 436 | curve: Curves.linearToEaseOut, 437 | reverseCurve: Curves.fastOutSlowIn); 438 | }, 439 | ), 440 | Divider( 441 | height: 0.5, 442 | ), 443 | ListTile( 444 | title: Text( 445 | 'normal toast(size anim)', 446 | ), 447 | onTap: () { 448 | showToast('This is normal toast with animation', 449 | context: context, 450 | animation: StyledToastAnimation.size, 451 | reverseAnimation: StyledToastAnimation.size, 452 | axis: Axis.horizontal, 453 | position: StyledToastPosition.center, 454 | animDuration: Duration(milliseconds: 400), 455 | duration: Duration(seconds: 2), 456 | curve: Curves.linear, 457 | reverseCurve: Curves.linear); 458 | }, 459 | ), 460 | Divider( 461 | height: 0.5, 462 | ), 463 | ListTile( 464 | title: Text( 465 | 'normal toast(sizefade anim)', 466 | ), 467 | onTap: () { 468 | showToast('This is normal toast with animation', 469 | context: context, 470 | animation: StyledToastAnimation.sizeFade, 471 | reverseAnimation: StyledToastAnimation.sizeFade, 472 | axis: Axis.horizontal, 473 | position: StyledToastPosition.center, 474 | animDuration: Duration(milliseconds: 400), 475 | duration: Duration(seconds: 2), 476 | curve: Curves.linear, 477 | reverseCurve: Curves.linear); 478 | }, 479 | ), 480 | Divider( 481 | height: 0.5, 482 | ), 483 | ListTile( 484 | title: Text( 485 | 'normal toast(scale anim)', 486 | ), 487 | onTap: () { 488 | showToast('This is normal toast with animation', 489 | context: context, 490 | animation: StyledToastAnimation.scale, 491 | reverseAnimation: StyledToastAnimation.fade, 492 | position: StyledToastPosition.center, 493 | animDuration: Duration(seconds: 1), 494 | duration: Duration(seconds: 4), 495 | curve: Curves.elasticOut, 496 | reverseCurve: Curves.linear); 497 | }, 498 | ), 499 | Divider( 500 | height: 0.5, 501 | ), 502 | ListTile( 503 | title: Text( 504 | 'Normal toast(fadeScale anim)', 505 | ), 506 | onTap: () { 507 | showToast('This is normal toast with animation', 508 | context: context, 509 | animation: StyledToastAnimation.fadeScale, 510 | reverseAnimation: StyledToastAnimation.scaleRotate, 511 | position: StyledToastPosition.center, 512 | animDuration: Duration(seconds: 1), 513 | duration: Duration(seconds: 4), 514 | curve: Curves.linear, 515 | reverseCurve: Curves.linear); 516 | }, 517 | ), 518 | Divider( 519 | height: 0.5, 520 | ), 521 | ListTile( 522 | title: Text( 523 | 'Normal toast(rotate anim)', 524 | ), 525 | onTap: () { 526 | showToast('This is normal toast with animation', 527 | context: context, 528 | animation: StyledToastAnimation.rotate, 529 | reverseAnimation: StyledToastAnimation.fadeRotate, 530 | position: StyledToastPosition.center, 531 | animDuration: Duration(seconds: 1), 532 | duration: Duration(seconds: 4), 533 | curve: Curves.elasticOut, 534 | reverseCurve: Curves.elasticIn); 535 | }, 536 | ), 537 | Divider( 538 | height: 0.5, 539 | ), 540 | ListTile( 541 | title: Text( 542 | 'Normal toast(fadeRotate anim)', 543 | ), 544 | onTap: () { 545 | showToast('This is normal toast with animation', 546 | context: context, 547 | animation: StyledToastAnimation.fadeRotate, 548 | reverseAnimation: StyledToastAnimation.fadeScale, 549 | position: StyledToastPosition.center, 550 | animDuration: Duration(seconds: 1), 551 | duration: Duration(seconds: 4), 552 | curve: Curves.linear, 553 | reverseCurve: Curves.linear); 554 | }, 555 | ), 556 | Divider( 557 | height: 0.5, 558 | ), 559 | ListTile( 560 | title: Text( 561 | 'Normal toast(scaleRotate anim)', 562 | ), 563 | onTap: () { 564 | showToast('This is normal toast with animation', 565 | context: context, 566 | animation: StyledToastAnimation.scaleRotate, 567 | reverseAnimation: StyledToastAnimation.fade, 568 | position: StyledToastPosition.center, 569 | animDuration: Duration(seconds: 1), 570 | duration: Duration(seconds: 4), 571 | curve: Curves.elasticOut, 572 | reverseCurve: Curves.linear); 573 | }, 574 | ), 575 | Divider( 576 | height: 0.5, 577 | ), 578 | ListTile( 579 | title: Text( 580 | 'Normal toast with onDismissed($dismissRemind)', 581 | ), 582 | onTap: () { 583 | setState(() { 584 | dismissRemind = ''; 585 | }); 586 | showToast( 587 | 'This is normal toast with onDismissed', 588 | context: context, 589 | animation: StyledToastAnimation.fade, 590 | duration: Duration(seconds: 2), 591 | animDuration: Duration(milliseconds: 1000), 592 | onDismiss: () { 593 | setState(() { 594 | dismissRemind = 'dismissed'; 595 | }); 596 | }, 597 | curve: Curves.decelerate, 598 | reverseCurve: Curves.linear, 599 | ); 600 | }, 601 | ), 602 | Divider( 603 | height: 10, 604 | thickness: 10, 605 | ), 606 | ListTile( 607 | title: Text( 608 | 'Normal toast(custom anim)', 609 | ), 610 | onTap: () async { 611 | showToast( 612 | 'This is normal toast with custom animation', 613 | context: context, 614 | animationBuilder: ( 615 | BuildContext context, 616 | AnimationController controller, 617 | Duration duration, 618 | Widget child, 619 | ) { 620 | return SlideTransition( 621 | position: getAnimation( 622 | Offset(0.0, 3.0), Offset(0, 0), controller, 623 | curve: Curves.bounceInOut), 624 | child: child, 625 | ); 626 | }, 627 | reverseAnimBuilder: ( 628 | BuildContext context, 629 | AnimationController controller, 630 | Duration duration, 631 | Widget child, 632 | ) { 633 | return SlideTransition( 634 | position: getAnimation( 635 | Offset(0.0, 0.0), Offset(-3.0, 0), controller, 636 | curve: Curves.bounceInOut), 637 | child: child, 638 | ); 639 | }, 640 | position: StyledToastPosition.bottom, 641 | animDuration: Duration(milliseconds: 1000), 642 | duration: Duration(seconds: 4), 643 | curve: Curves.elasticOut, 644 | reverseCurve: Curves.linear, 645 | ); 646 | }, 647 | ), 648 | Divider( 649 | height: 0.5, 650 | ), 651 | ListTile( 652 | title: Text( 653 | 'Normal toast(custom multiple anim)', 654 | ), 655 | onTap: () async { 656 | showToast( 657 | 'This is normal toast with custom multiple animation', 658 | context: context, 659 | animationBuilder: (context, controller, duration, child) { 660 | final scale = Tween(begin: 1.3, end: 1.0).animate( 661 | CurvedAnimation( 662 | parent: controller, 663 | curve: Curves.easeInSine, 664 | reverseCurve: Curves.easeOutSine), 665 | ); 666 | final sigma = Tween(begin: 0.0, end: 8.0).animate( 667 | CurvedAnimation( 668 | parent: controller, 669 | curve: Curves.easeInSine, 670 | reverseCurve: Curves.easeOutSine), 671 | ); 672 | final opacity = Tween(begin: 0.0, end: 1.0).animate( 673 | CurvedAnimation( 674 | parent: controller, 675 | curve: Curves.easeInSine, 676 | reverseCurve: Curves.easeOutSine), 677 | ); 678 | return ScaleTransition( 679 | scale: scale, 680 | child: ClipRRect( 681 | borderRadius: BorderRadius.circular(10), 682 | child: BlurTransition( 683 | sigma: sigma, 684 | child: FadeTransition( 685 | opacity: opacity, 686 | child: child, 687 | ), 688 | ))); 689 | }, 690 | reverseAnimBuilder: (context, controller, duration, child) { 691 | final sigma = Tween(begin: 10.0, end: 0.0).animate( 692 | CurvedAnimation( 693 | parent: controller, 694 | curve: Curves.easeOutSine, 695 | reverseCurve: Curves.easeInSine), 696 | ); 697 | final opacity = Tween(begin: 1.0, end: 0.0).animate( 698 | CurvedAnimation( 699 | parent: controller, 700 | curve: Curves.easeOutSine, 701 | reverseCurve: Curves.easeInSine), 702 | ); 703 | return ClipRRect( 704 | borderRadius: BorderRadius.circular(10), 705 | child: BlurTransition( 706 | sigma: sigma, 707 | child: FadeTransition( 708 | opacity: opacity, 709 | child: child, 710 | ), 711 | ), 712 | ); 713 | }, 714 | position: StyledToastPosition.bottom, 715 | animDuration: Duration(milliseconds: 1000), 716 | duration: Duration(seconds: 4), 717 | curve: Curves.elasticOut, 718 | reverseCurve: Curves.linear, 719 | ); 720 | }, 721 | ), 722 | Divider( 723 | height: 0.5, 724 | ), 725 | ListTile( 726 | title: Text( 727 | 'Normal toast(custom anim with custom animation controller)', 728 | ), 729 | onTap: () async { 730 | showToast( 731 | 'This is normal toast with custom animation', 732 | context: context, 733 | onInitState: 734 | (Duration toastDuration, Duration animDuration) async { 735 | try { 736 | await mController.forward().orCancel; 737 | Future.delayed(toastDuration - animDuration, () async { 738 | await mReverseController.forward().orCancel; 739 | mController.reset(); 740 | mReverseController.reset(); 741 | }); 742 | } on TickerCanceled {} 743 | }, 744 | animationBuilder: ( 745 | BuildContext context, 746 | AnimationController controller, 747 | Duration duration, 748 | Widget child, 749 | ) { 750 | return SlideTransition( 751 | position: getAnimation( 752 | Offset(0.0, 3.0), Offset(0, 0), mController, 753 | curve: Curves.bounceInOut), 754 | child: child, 755 | ); 756 | }, 757 | reverseAnimBuilder: ( 758 | BuildContext context, 759 | AnimationController controller, 760 | Duration duration, 761 | Widget child, 762 | ) { 763 | return SlideTransition( 764 | position: getAnimation( 765 | Offset(0.0, 0.0), Offset(-3.0, 0), mReverseController, 766 | curve: Curves.bounceInOut), 767 | child: child, 768 | ); 769 | }, 770 | position: StyledToastPosition.bottom, 771 | animDuration: Duration(milliseconds: 1000), 772 | duration: Duration(seconds: 4), 773 | curve: Curves.elasticOut, 774 | reverseCurve: Curves.linear, 775 | ); 776 | }, 777 | ), 778 | 779 | ///Custom toast content widget 780 | Container( 781 | margin: EdgeInsets.only(bottom: 10.0, top: 50.0), 782 | padding: EdgeInsets.only(left: 15.0), 783 | height: 35.0, 784 | alignment: Alignment.centerLeft, 785 | child: Text('Custom toast content widget'), 786 | color: const Color(0xFFDDDDDD), 787 | ), 788 | ListTile( 789 | title: Text( 790 | 'Custom toast content widget', 791 | ), 792 | onTap: () { 793 | showToastWidget(BannerToastWidget.fail(msg: 'Request failed'), 794 | context: context, 795 | animation: StyledToastAnimation.slideFromLeft, 796 | reverseAnimation: StyledToastAnimation.slideToLeft, 797 | alignment: Alignment.centerLeft, 798 | axis: Axis.horizontal, 799 | position: StyledToastPosition( 800 | align: Alignment.topCenter, offset: 0.0), 801 | startOffset: Offset(-1.0, 0.0), 802 | reverseEndOffset: Offset(-1.0, 0.0), 803 | animDuration: Duration(milliseconds: 400), 804 | duration: Duration(seconds: 2), 805 | curve: Curves.linearToEaseOut, 806 | reverseCurve: Curves.fastOutSlowIn); 807 | }, 808 | ), 809 | Divider( 810 | height: 0.5, 811 | ), 812 | ListTile( 813 | title: Text('Interactive toast'), 814 | onTap: () { 815 | showToastWidget( 816 | Container( 817 | padding: EdgeInsets.symmetric(horizontal: 18.0), 818 | margin: EdgeInsets.symmetric(horizontal: 50.0), 819 | decoration: ShapeDecoration( 820 | shape: RoundedRectangleBorder( 821 | borderRadius: BorderRadius.circular(5.0), 822 | ), 823 | color: Colors.green[600], 824 | ), 825 | child: Row( 826 | children: [ 827 | Text( 828 | 'Jump to new page', 829 | style: TextStyle( 830 | color: Colors.white, 831 | ), 832 | ), 833 | IconButton( 834 | onPressed: () { 835 | dismissAllToast(showAnim: true); 836 | Navigator.push(context, 837 | MaterialPageRoute(builder: (context) { 838 | return SecondPage(); 839 | })); 840 | }, 841 | icon: Icon( 842 | Icons.add_circle_outline_outlined, 843 | color: Colors.white, 844 | ), 845 | ), 846 | ], 847 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 848 | ), 849 | ), 850 | context: context, 851 | isIgnoring: false, 852 | duration: Duration.zero, 853 | ); 854 | }, 855 | ), 856 | Divider( 857 | height: 0.5, 858 | ), 859 | ListTile( 860 | title: Text( 861 | 'Custom toast content widget with icon convinient fail', 862 | ), 863 | onTap: () { 864 | showToastWidget(IconToastWidget.fail(msg: 'failed'), 865 | context: context, 866 | position: StyledToastPosition.center, 867 | animation: StyledToastAnimation.scale, 868 | reverseAnimation: StyledToastAnimation.fade, 869 | duration: Duration(seconds: 4), 870 | animDuration: Duration(seconds: 1), 871 | curve: Curves.elasticOut, 872 | reverseCurve: Curves.linear); 873 | }, 874 | ), 875 | Divider( 876 | height: 0.5, 877 | ), 878 | ListTile( 879 | title: Text( 880 | 'Custom toast content widget with icon convenient success', 881 | ), 882 | onTap: () { 883 | showToastWidget(IconToastWidget.success(msg: 'success'), 884 | context: context, 885 | position: StyledToastPosition.center, 886 | animation: StyledToastAnimation.scale, 887 | reverseAnimation: StyledToastAnimation.fade, 888 | duration: Duration(seconds: 4), 889 | animDuration: Duration(seconds: 1), 890 | curve: Curves.elasticOut, 891 | reverseCurve: Curves.linear); 892 | }, 893 | ), 894 | Divider( 895 | height: 0.5, 896 | ), 897 | ], 898 | ), 899 | ), 900 | ); 901 | } 902 | } 903 | 904 | // The StatefulWidget's job is to take in some data and create a State class. 905 | // In this case, the Widget takes a title, and creates a _MyHomePageState. 906 | class SecondPage extends StatefulWidget { 907 | final String? title; 908 | 909 | SecondPage({Key? key, this.title}) : super(key: key); 910 | 911 | @override 912 | _SecondPageState createState() => _SecondPageState(); 913 | } 914 | 915 | // The State class is responsible for two things: holding some data you can 916 | // update and building the UI using that data. 917 | class _SecondPageState extends State { 918 | // Whether the green box should be visible or invisible 919 | 920 | @override 921 | Widget build(BuildContext context) { 922 | Color getColor(Set states) { 923 | const Set interactiveStates = { 924 | MaterialState.pressed, 925 | MaterialState.hovered, 926 | MaterialState.focused, 927 | }; 928 | if (states.any(interactiveStates.contains)) { 929 | return Colors.blue; 930 | } 931 | return Colors.red; 932 | } 933 | 934 | return Scaffold( 935 | appBar: AppBar( 936 | title: Text(widget.title ?? 'Second Page'), 937 | ), 938 | body: Center( 939 | child: ListView( 940 | padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 20.0), 941 | children: [ 942 | Container( 943 | margin: EdgeInsets.only(bottom: 10.0), 944 | padding: EdgeInsets.only(left: 15.0), 945 | height: 35.0, 946 | alignment: Alignment.centerLeft, 947 | child: Text('second page Toast'), 948 | color: const Color(0xFFDDDDDD), 949 | ), 950 | Container( 951 | height: 50.0, 952 | margin: EdgeInsets.only(bottom: 20.0), 953 | child: ElevatedButton( 954 | onPressed: () { 955 | showToast( 956 | 'This is normal toast', 957 | ); 958 | }, 959 | style: ButtonStyle( 960 | backgroundColor: 961 | MaterialStateProperty.resolveWith(getColor)), 962 | child: Text( 963 | 'normal toast', 964 | style: TextStyle(fontSize: 15.0, color: Colors.white), 965 | ), 966 | ), 967 | ), 968 | ], 969 | ), 970 | ), 971 | ); 972 | } 973 | } 974 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_styled_toast_example 2 | description: A new Flutter application. 3 | 4 | publish_to: 'none' 5 | 6 | version: 2.0.0 7 | 8 | environment: 9 | sdk: ">=3.0.0 <4.0.0" 10 | 11 | dependencies: 12 | cupertino_icons: ^1.0.5 13 | flutter: 14 | sdk: flutter 15 | flutter_styled_toast: 16 | path: ../ 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | 22 | flutter: 23 | uses-material-design: true 24 | assets: 25 | - assets/ 26 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | void main() {} 9 | -------------------------------------------------------------------------------- /lib/flutter_styled_toast.dart: -------------------------------------------------------------------------------- 1 | library flutter_styled_toast; 2 | 3 | export 'src/styled_toast.dart' show showToast, showToastWidget, StyledToast; 4 | export 'src/styled_toast_enum.dart'; 5 | export 'src/styled_toast_manage.dart'; 6 | export 'src/custom_size_transition.dart'; 7 | export 'src/custom_animation.dart'; 8 | export 'src/styled_toast_theme.dart'; 9 | -------------------------------------------------------------------------------- /lib/src/custom_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Builder method for custom animation. 4 | /// 5 | /// Get custom animation widget for the [child] toast widget, 6 | /// you can use the internal or external [controller]. 7 | typedef CustomAnimationBuilder = Widget Function( 8 | BuildContext context, 9 | AnimationController controller, 10 | Duration duration, 11 | Widget child, 12 | ); 13 | 14 | /// Get the animation simply. 15 | /// 16 | /// Get the curved [Animation] object conveniently from [start], [end] value drove by the controller. 17 | Animation getAnimation( 18 | T start, 19 | T end, 20 | AnimationController controller, { 21 | Curve curve = Curves.linearToEaseOut, 22 | }) { 23 | return controller 24 | .drive(Tween(begin: start, end: end).chain(CurveTween(curve: curve))); 25 | } 26 | -------------------------------------------------------------------------------- /lib/src/custom_size_transition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'dart:math' as math; 3 | 4 | /// Animates its own size and clips and aligns its child. 5 | /// 6 | /// [CustomSizeTransition] acts as a [ClipRect] that animates either its width or its 7 | /// height, depending upon the value of [axis]. The alignment of the child along 8 | /// the [axis] is specified by the [axisAlignment]. 9 | /// 10 | /// Like most widgets, [CustomSizeTransition] will conform to the constraints it is 11 | /// given, so be sure to put it in a context where it can change size. For 12 | /// instance, if you place it into a [Container] with a fixed size, then the 13 | /// [CustomSizeTransition] will not be able to change size, and will appear to do 14 | /// nothing. 15 | /// 16 | /// Here's an illustration of the [CustomSizeTransition] widget, with it's [sizeFactor] 17 | /// animated by a [CurvedAnimation] set to [Curves.fastOutSlowIn]: 18 | /// {@animation 300 378 https://flutter.github.io/assets-for-api-docs/assets/widgets/size_transition.mp4} 19 | /// 20 | /// See also: 21 | /// 22 | /// * [AnimatedCrossFade], for a widget that automatically animates between 23 | /// the sizes of two children, fading between them. 24 | /// * [ScaleTransition], a widget that scales the size of the child instead of 25 | /// clipping it. 26 | /// * [PositionedTransition], a widget that animates its child from a start 27 | /// position to an end position over the lifetime of the animation. 28 | /// * [RelativePositionedTransition], a widget that transitions its child's 29 | /// position based on the value of a rectangle relative to a bounding box. 30 | class CustomSizeTransition extends AnimatedWidget { 31 | /// Creates a size transition. 32 | /// 33 | /// The [axis], [sizeFactor], and [axisAlignment] arguments must not be null. 34 | /// The [axis] argument defaults to [Axis.vertical]. The [axisAlignment] 35 | /// defaults to 0.0, which centers the child along the main axis during the 36 | /// transition. 37 | const CustomSizeTransition({ 38 | Key? key, 39 | this.axis = Axis.vertical, 40 | this.alignment, 41 | required Animation sizeFactor, 42 | this.axisAlignment = 0.0, 43 | this.child, 44 | }) : super(key: key, listenable: sizeFactor); 45 | 46 | /// [Axis.horizontal] if [sizeFactor] modifies the width, otherwise 47 | /// [Axis.vertical]. 48 | final Axis axis; 49 | 50 | final AlignmentGeometry? alignment; 51 | 52 | /// The animation that controls the (clipped) size of the child. 53 | /// 54 | /// The width or height (depending on the [axis] value) of this widget will be 55 | /// its intrinsic width or height multiplied by [sizeFactor]'s value at the 56 | /// current point in the animation. 57 | /// 58 | /// If the value of [sizeFactor] is less than one, the child will be clipped 59 | /// in the appropriate axis. 60 | Animation get sizeFactor => listenable as Animation; 61 | 62 | /// Describes how to align the child along the axis that [sizeFactor] is 63 | /// modifying. 64 | /// 65 | /// A value of -1.0 indicates the top when [axis] is [Axis.vertical], and the 66 | /// start when [axis] is [Axis.horizontal]. The start is on the left when the 67 | /// text direction in effect is [TextDirection.ltr] and on the right when it 68 | /// is [TextDirection.rtl]. 69 | /// 70 | /// A value of 1.0 indicates the bottom or end, depending upon the [axis]. 71 | /// 72 | /// A value of 0.0 (the default) indicates the center for either [axis] value. 73 | final double axisAlignment; 74 | 75 | /// The widget below this widget in the tree. 76 | /// 77 | /// {@macro flutter.widgets.child} 78 | final Widget? child; 79 | 80 | @override 81 | Widget build(BuildContext context) { 82 | final alignmentDirect = axis == Axis.vertical 83 | ? AlignmentDirectional(-1.0, axisAlignment) 84 | : AlignmentDirectional(axisAlignment, -1.0); 85 | return ClipRect( 86 | child: Align( 87 | alignment: alignment ?? alignmentDirect, 88 | heightFactor: 89 | axis == Axis.vertical ? math.max(sizeFactor.value, 0.0) : null, 90 | widthFactor: 91 | axis == Axis.horizontal ? math.max(sizeFactor.value, 0.0) : null, 92 | child: child, 93 | ), 94 | ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /lib/src/styled_toast_enum.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | /// Toast position. 4 | class StyledToastPosition { 5 | /// Toast position align. 6 | final Alignment align; 7 | 8 | /// Toast position offset. 9 | /// 10 | /// if align is topLeft/topCenter/topRight, offset is the distance from top, 11 | /// if align is centerLeft, offset is the distance from left, 12 | /// if align is centerRight, offset is the distance from right, 13 | /// if align is bottomLeft/bottomCenter/bottomRight, offset is the distance from bottom. 14 | final double offset; 15 | 16 | const StyledToastPosition({this.align = Alignment.center, this.offset = 0.0}); 17 | 18 | /// Center position. 19 | static const center = 20 | StyledToastPosition(align: Alignment.center, offset: 0.0); 21 | 22 | /// Top center position. 23 | static const top = 24 | StyledToastPosition(align: Alignment.topCenter, offset: 10.0); 25 | 26 | /// Bottom center position. 27 | static const bottom = 28 | StyledToastPosition(align: Alignment.bottomCenter, offset: 20.0); 29 | 30 | /// Center left position. 31 | static const left = 32 | StyledToastPosition(align: Alignment.centerLeft, offset: 17.0); 33 | 34 | /// Center right position. 35 | static const right = 36 | StyledToastPosition(align: Alignment.centerRight, offset: 17.0); 37 | } 38 | 39 | /// Toast showing type. 40 | enum StyledToastShowType { 41 | /// Dismiss old toast widget that is showing. 42 | dismissShowing, 43 | 44 | /// Show a new toast. 45 | normal, 46 | } 47 | 48 | /// Toast animation. 49 | enum StyledToastAnimation { 50 | /// Fade in and out animation. 51 | fade, 52 | 53 | /// Slide from top animation. 54 | slideFromTop, 55 | 56 | /// Slide from top fade animation. 57 | slideFromTopFade, 58 | 59 | /// Slide from bottom animation. 60 | slideFromBottom, 61 | 62 | /// Slide from bottom fade animation. 63 | slideFromBottomFade, 64 | 65 | /// Slide from left animation. 66 | slideFromLeft, 67 | 68 | /// Slide from left fade animation. 69 | slideFromLeftFade, 70 | 71 | /// Slide from right animation. 72 | slideFromRight, 73 | 74 | /// Slide from right fade animation. 75 | slideFromRightFade, 76 | 77 | /// Slide to top animation. 78 | slideToTop, 79 | 80 | /// Slide to top fade animation. 81 | slideToTopFade, 82 | 83 | /// Slide to bottom animation. 84 | slideToBottom, 85 | 86 | /// Slide to bottom fade animation. 87 | slideToBottomFade, 88 | 89 | /// Slide to left animation. 90 | slideToLeft, 91 | 92 | /// Slide to left fade animation. 93 | slideToLeftFade, 94 | 95 | /// Slide to right animation. 96 | slideToRight, 97 | 98 | /// Slide to right fade animation. 99 | slideToRightFade, 100 | 101 | /// Scale animation. 102 | scale, 103 | 104 | /// Size animation. 105 | size, 106 | 107 | /// Size fade animation. 108 | sizeFade, 109 | 110 | /// Fade scale animation. 111 | fadeScale, 112 | 113 | /// Rotate animation. 114 | rotate, 115 | 116 | /// Fade rotate animation. 117 | fadeRotate, 118 | 119 | /// Scale rotate animation. 120 | scaleRotate, 121 | 122 | /// No animation. 123 | none, 124 | } 125 | -------------------------------------------------------------------------------- /lib/src/styled_toast_manage.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/widgets.dart'; 4 | 5 | import 'styled_toast.dart'; 6 | 7 | /// The method to dismiss all toast. 8 | void dismissAllToast({bool showAnim = false}) { 9 | ToastManager().dismissAll(showAnim: showAnim); 10 | } 11 | 12 | /// The class for managing the overlay and dismiss. 13 | /// 14 | /// Use the [dismiss] to dismiss toast. 15 | /// When the Toast is dismissed, call [onDismiss] if specified. 16 | class ToastFuture { 17 | /// Toast overlay. 18 | final OverlayEntry _entry; 19 | 20 | /// Callback when toast dismiss. 21 | final VoidCallback? _onDismiss; 22 | 23 | ///Toast widget key. 24 | final GlobalKey _containerKey; 25 | 26 | ///Is toast showing. 27 | bool _isShow = true; 28 | 29 | /// A [Timer] used to dismiss this toast future after the given period of time. 30 | Timer? _timer; 31 | 32 | /// Get the [_entry]. 33 | OverlayEntry get entry => _entry; 34 | 35 | /// Get the [_onDismiss]. 36 | VoidCallback? get onDismiss => _onDismiss; 37 | 38 | /// Get the [_isShow]. 39 | bool get isShow => _isShow; 40 | 41 | /// Get the [_containerKey] 42 | GlobalKey get containerKey => _containerKey; 43 | 44 | ToastFuture.create( 45 | Duration duration, 46 | this._entry, 47 | this._onDismiss, 48 | this._containerKey, 49 | ) { 50 | if (duration != Duration.zero) { 51 | _timer = Timer(duration, () => dismiss()); 52 | } 53 | } 54 | 55 | /// Dismiss toast overlay. 56 | /// 57 | /// [showAnim] Can be used to dismiss a toast with animation effect or not. 58 | Future dismiss({ 59 | bool showAnim = false, 60 | }) async { 61 | if (!_isShow) { 62 | return; 63 | } 64 | 65 | _isShow = false; 66 | _timer?.cancel(); 67 | _onDismiss?.call(); 68 | ToastManager().removeFuture(this); 69 | if (showAnim) { 70 | await _containerKey.currentState?.dismissToastAnim(); 71 | } else { 72 | _containerKey.currentState?.dismissToast(); 73 | } 74 | _entry.remove(); 75 | } 76 | } 77 | 78 | /// Toast manager, manage toast list. 79 | class ToastManager { 80 | ToastManager._(); 81 | 82 | /// Instance of [ToastManager]. 83 | static ToastManager? _instance; 84 | 85 | /// Factory to create [ToastManager] singleton. 86 | factory ToastManager() { 87 | _instance ??= ToastManager._(); 88 | return _instance!; 89 | } 90 | 91 | /// [Set] used to save [ToastFuture]. 92 | Set toastSet = {}; 93 | 94 | /// Dismiss all toast. 95 | void dismissAll({ 96 | bool showAnim = false, 97 | }) { 98 | toastSet.toList().forEach((v) { 99 | v.dismiss(showAnim: showAnim); 100 | }); 101 | } 102 | 103 | /// Remove [ToastFuture]. 104 | void removeFuture(ToastFuture future) { 105 | toastSet.remove(future); 106 | } 107 | 108 | /// Add [ToastFuture]. 109 | void addFuture(ToastFuture future) { 110 | toastSet.add(future); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /lib/src/styled_toast_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'custom_animation.dart'; 3 | import 'styled_toast.dart'; 4 | import 'styled_toast_enum.dart'; 5 | 6 | /// Toast theme, only for default content widget. 7 | /// 8 | /// If you have specified a custom content widget, [ToastTheme] will not be working. 9 | class StyledToastTheme extends InheritedWidget { 10 | /// Text align. 11 | final TextAlign? textAlign; 12 | 13 | /// Text direction. 14 | final TextDirection? textDirection; 15 | 16 | /// Border radius. 17 | final BorderRadius? borderRadius; 18 | 19 | /// Background color. 20 | final Color? backgroundColor; 21 | 22 | /// Padding for the text and the container edges. 23 | final EdgeInsets? textPadding; 24 | 25 | /// Text style for content. 26 | final TextStyle? textStyle; 27 | 28 | /// Shape for the container. 29 | final ShapeBorder? shapeBorder; 30 | 31 | /// Toast show duration. 32 | final Duration? duration; 33 | 34 | /// Toast animation duration. 35 | final Duration? animDuration; 36 | 37 | /// Position of the toast widget in current window. 38 | final StyledToastPosition? toastPositions; 39 | 40 | /// Alignment of animation, like size, rotate animation. 41 | final Alignment? alignment; 42 | 43 | /// Axis of animation, like size animation. 44 | final Axis? axis; 45 | 46 | /// Start offset of slide animation. 47 | final Offset? startOffset; 48 | 49 | /// End offset of slide animation. 50 | final Offset? endOffset; 51 | 52 | /// Start offset of reverse slide animation. 53 | final Offset? reverseStartOffset; 54 | 55 | /// End offset of reverse slide animation. 56 | final Offset? reverseEndOffset; 57 | 58 | /// Toast animation. 59 | final StyledToastAnimation? toastAnimation; 60 | 61 | /// Toast reverse animation. 62 | final StyledToastAnimation? reverseAnimation; 63 | 64 | /// Animation curve. 65 | final Curve? curve; 66 | 67 | /// Animation reverse curve. 68 | final Curve? reverseCurve; 69 | 70 | /// Dismiss old toast when new one shows. 71 | final bool? dismissOtherOnShow; 72 | 73 | /// Callback when toast dismissed. 74 | final VoidCallback? onDismiss; 75 | 76 | /// Full width that the width of the screen minus the width of the margin. 77 | final bool? fullWidth; 78 | 79 | /// Is hide keyboard when toast show. 80 | final bool? isHideKeyboard; 81 | 82 | /// Custom animation builder method. 83 | final CustomAnimationBuilder? animationBuilder; 84 | 85 | /// Custom animation builder method. 86 | final CustomAnimationBuilder? reverseAnimBuilder; 87 | 88 | /// Is the input ignored for the toast. 89 | final bool? isIgnoring; 90 | 91 | /// When toast widget [initState], this callback will be called. 92 | final OnInitStateCallback? onInitState; 93 | 94 | const StyledToastTheme({ 95 | super.key, 96 | required super.child, 97 | this.textAlign, 98 | this.textDirection, 99 | this.borderRadius, 100 | this.backgroundColor, 101 | this.textPadding, 102 | this.textStyle, 103 | this.shapeBorder, 104 | this.duration, 105 | this.animDuration, 106 | this.toastPositions, 107 | this.alignment, 108 | this.axis, 109 | this.startOffset, 110 | this.endOffset, 111 | this.reverseStartOffset, 112 | this.reverseEndOffset, 113 | this.toastAnimation, 114 | this.reverseAnimation, 115 | this.curve, 116 | this.reverseCurve, 117 | this.dismissOtherOnShow, 118 | this.onDismiss, 119 | this.fullWidth, 120 | this.isHideKeyboard, 121 | this.animationBuilder, 122 | this.reverseAnimBuilder, 123 | this.isIgnoring, 124 | this.onInitState, 125 | }); 126 | 127 | @override 128 | bool updateShouldNotify(InheritedWidget oldWidget) { 129 | return true; 130 | } 131 | 132 | /// Get the [StyledToastTheme] object. 133 | static StyledToastTheme of(BuildContext context) => 134 | context.dependOnInheritedWidgetOfExactType()!; 135 | 136 | /// Try to find the [StyledToastTheme] object in the widgets tree. 137 | static StyledToastTheme? maybeOf(BuildContext context) => 138 | context.dependOnInheritedWidgetOfExactType(); 139 | } 140 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_styled_toast 2 | description: A Styled Toast Flutter package. You can highly customize toast 3 | ever.Beautify toast with a series of animations and make toast more beautiful. 4 | version: 2.2.1 5 | homepage: https://github.com/JackJonson/flutter_styled_toast 6 | email: yswing1@gmail.com 7 | 8 | environment: 9 | sdk: ">=3.0.0 <4.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | flutter_localizations: 15 | sdk: flutter 16 | 17 | dev_dependencies: 18 | flutter_driver: 19 | sdk: flutter 20 | flutter_lints: ^2.0.2 21 | flutter_test: 22 | sdk: flutter 23 | 24 | flutter: null 25 | -------------------------------------------------------------------------------- /screenshots/CustomFailToastWidget.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/CustomFailToastWidget.gif -------------------------------------------------------------------------------- /screenshots/CustomSuccessToastWidget.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/CustomSuccessToastWidget.gif -------------------------------------------------------------------------------- /screenshots/CustomToastWidget.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/CustomToastWidget.gif -------------------------------------------------------------------------------- /screenshots/DefaultToastWidget.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/DefaultToastWidget.gif -------------------------------------------------------------------------------- /screenshots/FadeAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/FadeAnim.gif -------------------------------------------------------------------------------- /screenshots/FadeRotateAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/FadeRotateAnim.gif -------------------------------------------------------------------------------- /screenshots/FadeScaleAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/FadeScaleAnim.gif -------------------------------------------------------------------------------- /screenshots/OnDismiss.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/OnDismiss.gif -------------------------------------------------------------------------------- /screenshots/OverallAnimations.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/OverallAnimations.gif -------------------------------------------------------------------------------- /screenshots/RotateAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/RotateAnim.gif -------------------------------------------------------------------------------- /screenshots/ScaleAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/ScaleAnim.gif -------------------------------------------------------------------------------- /screenshots/ScaleRotateAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/ScaleRotateAnim.gif -------------------------------------------------------------------------------- /screenshots/SlideFromBottomAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/SlideFromBottomAnim.gif -------------------------------------------------------------------------------- /screenshots/SlideFromLeftAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/SlideFromLeftAnim.gif -------------------------------------------------------------------------------- /screenshots/SlideFromRightAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/SlideFromRightAnim.gif -------------------------------------------------------------------------------- /screenshots/SlideFromTopAnim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackJonson/flutter_styled_toast/5fc1f300712a166c296c349fa998304f374d4288/screenshots/SlideFromTopAnim.gif -------------------------------------------------------------------------------- /start_build_release_apk.bat: -------------------------------------------------------------------------------- 1 | flutter clean && flutter build apk --release --target-platform android-arm -------------------------------------------------------------------------------- /test/custom_animation_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | void main() { 6 | group('custom animation', () { 7 | testWidgets('CustomAnimation', (WidgetTester tester) async { 8 | final GlobalKey key = GlobalKey(); 9 | final testAppWidget = CustomAnimationTestAppWidget(key: key); 10 | await tester.pumpWidget(testAppWidget); 11 | 12 | showToastWidget( 13 | const Text('custom widget'), 14 | duration: const Duration(seconds: 4), 15 | animDuration: const Duration(seconds: 2), 16 | position: StyledToastPosition.bottom, 17 | onDismiss: () {}, 18 | textDirection: TextDirection.ltr, 19 | dismissOtherToast: true, 20 | animation: StyledToastAnimation.slideFromBottom, 21 | reverseAnimation: StyledToastAnimation.slideToLeftFade, 22 | alignment: Alignment.center, 23 | axis: Axis.horizontal, 24 | startOffset: const Offset(0, 1.0), 25 | endOffset: const Offset(0, 0), 26 | reverseStartOffset: const Offset(0, 0), 27 | reverseEndOffset: const Offset(-1, 0), 28 | curve: Curves.decelerate, 29 | reverseCurve: Curves.linear, 30 | isHideKeyboard: true, 31 | isIgnoring: true, 32 | animationBuilder: ( 33 | BuildContext context, 34 | AnimationController controller, 35 | Duration duration, 36 | Widget child, 37 | ) { 38 | return SlideTransition( 39 | position: getAnimation( 40 | const Offset(0.0, 3.0), 41 | const Offset(0, 0), 42 | key.currentState!.animationController, 43 | curve: Curves.bounceInOut, 44 | ), 45 | child: child, 46 | ); 47 | }, 48 | reverseAnimBuilder: ( 49 | BuildContext context, 50 | AnimationController controller, 51 | Duration duration, 52 | Widget child, 53 | ) { 54 | return SlideTransition( 55 | position: getAnimation( 56 | const Offset(0.0, 0.0), 57 | const Offset(-3.0, 0), 58 | key.currentState!.reverseAnimationController, 59 | curve: Curves.bounceInOut, 60 | ), 61 | child: child, 62 | ); 63 | }, 64 | ); 65 | await tester.pump(const Duration(milliseconds: 100)); 66 | 67 | expect(find.text('custom widget'), findsOneWidget); 68 | 69 | await tester.pump(const Duration(seconds: 4)); 70 | 71 | expect(find.text('custom widget'), findsNothing); 72 | }); 73 | }); 74 | } 75 | 76 | class CustomAnimationTestAppWidget extends StatefulWidget { 77 | const CustomAnimationTestAppWidget({super.key}); 78 | 79 | @override 80 | CustomAnimationTestAppWidgetState createState() => 81 | CustomAnimationTestAppWidgetState(); 82 | } 83 | 84 | class CustomAnimationTestAppWidgetState 85 | extends State with TickerProviderStateMixin { 86 | late AnimationController _mController; 87 | late AnimationController _mReverseController; 88 | 89 | AnimationController get animationController => _mController; 90 | AnimationController get reverseAnimationController => _mReverseController; 91 | 92 | @override 93 | void initState() { 94 | super.initState(); 95 | 96 | _mController = AnimationController( 97 | vsync: this, 98 | duration: const Duration(milliseconds: 200), 99 | ); 100 | _mReverseController = AnimationController( 101 | vsync: this, 102 | duration: const Duration(milliseconds: 200), 103 | ); 104 | } 105 | 106 | @override 107 | Widget build(BuildContext context) { 108 | const appTitle = 'Styled Toast Example'; 109 | return StyledToast( 110 | textStyle: const TextStyle(fontSize: 16.0, color: Colors.white), 111 | backgroundColor: const Color(0x99000000), 112 | borderRadius: BorderRadius.circular(5.0), 113 | textPadding: const EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0), 114 | toastAnimation: StyledToastAnimation.size, 115 | reverseAnimation: StyledToastAnimation.size, 116 | startOffset: const Offset(0.0, -1.0), 117 | reverseEndOffset: const Offset(0.0, -1.0), 118 | duration: const Duration(seconds: 4), 119 | animDuration: const Duration(seconds: 1), 120 | alignment: Alignment.center, 121 | toastPositions: StyledToastPosition.center, 122 | curve: Curves.fastOutSlowIn, 123 | reverseCurve: Curves.fastOutSlowIn, 124 | dismissOtherOnShow: true, 125 | locale: const Locale('en', 'US'), 126 | fullWidth: false, 127 | isHideKeyboard: false, 128 | isIgnoring: true, 129 | child: MaterialApp( 130 | title: appTitle, 131 | home: LayoutBuilder( 132 | builder: (BuildContext context, BoxConstraints constraints) { 133 | return Container( 134 | color: Colors.blue, 135 | ); 136 | }, 137 | ), 138 | ), 139 | ); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /test/custom_size_transition_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | void main() { 6 | group('custom size transition', () { 7 | var statusList = []; 8 | testWidgets('Custom size transition', (WidgetTester tester) async { 9 | final child = MaterialApp( 10 | home: LayoutBuilder( 11 | builder: (BuildContext context, BoxConstraints constraints) { 12 | return TestWidget(statusList.add); 13 | }, 14 | ), 15 | ); 16 | await tester.pumpWidget(child); 17 | await tester.pump(const Duration(milliseconds: 10)); 18 | await tester.pump(const Duration(milliseconds: 1000)); 19 | 20 | expect(statusList, [AnimationStatus.forward, AnimationStatus.completed]); 21 | }); 22 | }); 23 | } 24 | 25 | class TestWidget extends StatefulWidget { 26 | final Function(AnimationStatus value) valueCallback; 27 | 28 | const TestWidget(this.valueCallback, {super.key}); 29 | 30 | @override 31 | State createState() => _TestWidgetState(); 32 | } 33 | 34 | class _TestWidgetState extends State with TickerProviderStateMixin { 35 | late Animation animation; 36 | late AnimationController animationController; 37 | @override 38 | void initState() { 39 | super.initState(); 40 | animationController = AnimationController( 41 | vsync: this, 42 | duration: const Duration(milliseconds: 1000), 43 | ); 44 | animationController.addStatusListener((status) { 45 | widget.valueCallback(status); 46 | }); 47 | animation = Tween(begin: 0.0, end: 1.0).animate( 48 | animationController, 49 | ); 50 | animationController.forward(); 51 | } 52 | 53 | @override 54 | void dispose() { 55 | animationController.dispose(); 56 | super.dispose(); 57 | } 58 | 59 | @override 60 | Widget build(BuildContext context) { 61 | return CustomSizeTransition( 62 | sizeFactor: animation, 63 | child: Container( 64 | width: 100, 65 | height: 100, 66 | color: Colors.blue, 67 | child: const Text('test1'), 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /test/styled_toast_manage_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | import 'styled_toast_test.dart'; 6 | 7 | void main() { 8 | group('ToastFuture', () { 9 | testWidgets('Create, store and dismiss a toast future', 10 | (WidgetTester tester) async { 11 | OverlayEntry entry = OverlayEntry(builder: (BuildContext context) { 12 | return const Text('toast future'); 13 | }); 14 | final GlobalKey key = GlobalKey(); 15 | final testAppWidget = TestAppWidget(overlayEntry: entry, key: key); 16 | await tester.pumpWidget(testAppWidget); 17 | 18 | ToastFuture toastFuture = ToastFuture.create(const Duration(seconds: 4), 19 | entry, () {}, GlobalKey(debugLabel: 'toast future global key')); 20 | final toastManager = ToastManager(); 21 | toastManager.addFuture(toastFuture); 22 | 23 | key.currentState?.insertEntry(); 24 | 25 | ///After inserting entry, need to trigger a new frame to paint the overlay entry. 26 | await tester.pump(); 27 | 28 | expect(find.text('toast future'), findsOneWidget); 29 | 30 | expect(entry.mounted, true); 31 | 32 | toastFuture.dismiss(showAnim: true); 33 | 34 | await tester.pump(const Duration(seconds: 4)); 35 | await tester.pump(const Duration(milliseconds: 100)); 36 | 37 | expect(entry.mounted, false); 38 | }); 39 | }); 40 | group('ToastManager', () { 41 | testWidgets('Add and remove ToastFuture', (WidgetTester tester) async { 42 | OverlayEntry entry = OverlayEntry(builder: (BuildContext context) { 43 | return const Text('toast future'); 44 | }); 45 | final GlobalKey key = GlobalKey(); 46 | final testAppWidget = TestAppWidget(overlayEntry: entry, key: key); 47 | await tester.pumpWidget(testAppWidget); 48 | 49 | ToastFuture toastFuture = ToastFuture.create(const Duration(seconds: 4), 50 | entry, () {}, GlobalKey(debugLabel: 'toast future global key')); 51 | 52 | key.currentState?.insertEntry(); 53 | toastFuture.dismiss(showAnim: true); 54 | 55 | expect(ToastManager().toastSet.length, 0); 56 | 57 | ToastManager().addFuture(toastFuture); 58 | expect(ToastManager().toastSet.length, 1); 59 | ToastManager().removeFuture(toastFuture); 60 | expect(ToastManager().toastSet.length, 0); 61 | }); 62 | 63 | testWidgets('All toast should be dismissed', (WidgetTester tester) async { 64 | final GlobalKey key = GlobalKey(); 65 | final testAppWidget = TestAppWidget(key: key); 66 | await tester.pumpWidget(testAppWidget); 67 | for (int i = 0; i < 4; i++) { 68 | showToast('toast$i', 69 | dismissOtherToast: false, duration: const Duration(seconds: 10)); 70 | } 71 | await tester.pump(const Duration(milliseconds: 100)); 72 | 73 | expect(find.text('toast0'), findsOneWidget); 74 | expect(find.text('toast1'), findsOneWidget); 75 | expect(find.text('toast2'), findsOneWidget); 76 | expect(find.text('toast3'), findsOneWidget); 77 | 78 | dismissAllToast(); 79 | 80 | await tester.pump(const Duration(milliseconds: 100)); 81 | 82 | expect(find.text('toast0'), findsNothing); 83 | expect(find.text('toast1'), findsNothing); 84 | expect(find.text('toast2'), findsNothing); 85 | expect(find.text('toast3'), findsNothing); 86 | 87 | for (int i = 4; i < 8; i++) { 88 | showToast('toast$i', 89 | dismissOtherToast: false, duration: const Duration(seconds: 10)); 90 | } 91 | await tester.pump(const Duration(milliseconds: 100)); 92 | 93 | expect(find.text('toast4'), findsOneWidget); 94 | expect(find.text('toast5'), findsOneWidget); 95 | expect(find.text('toast6'), findsOneWidget); 96 | expect(find.text('toast7'), findsOneWidget); 97 | 98 | ToastManager().dismissAll(showAnim: true); 99 | 100 | await tester.pump(const Duration(milliseconds: 100)); 101 | 102 | expect(find.text('toast4'), findsNothing); 103 | expect(find.text('toast5'), findsNothing); 104 | expect(find.text('toast6'), findsNothing); 105 | expect(find.text('toast7'), findsNothing); 106 | }); 107 | }); 108 | } 109 | -------------------------------------------------------------------------------- /test/styled_toast_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | void main() { 6 | group('StyleToastWidget', () { 7 | testWidgets('Create StyleToastWidget', (WidgetTester tester) async { 8 | const textStyle = TextStyle(fontSize: 16.0, color: Colors.white); 9 | const backgroundColor = Color(0x99000000); 10 | const borderRadius = BorderRadius.all(Radius.circular(5.0)); 11 | const textPadding = 12 | EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0); 13 | const toastAnimation = StyledToastAnimation.size; 14 | const reverseAnimation = StyledToastAnimation.size; 15 | const startOffset = Offset(0.0, -1.0); 16 | const reverseEndOffset = Offset(0.0, -1.0); 17 | const duration = Duration(seconds: 4); 18 | const animDuration = Duration(seconds: 1); 19 | const alignment = Alignment.center; 20 | const toastPositions = StyledToastPosition.center; 21 | const curve = Curves.fastOutSlowIn; 22 | const reverseCurve = Curves.fastOutSlowIn; 23 | const dismissOtherOnShow = true; 24 | const fullWidth = false; 25 | const isHideKeyboard = false; 26 | const isIgnoring = true; 27 | final child = MaterialApp( 28 | home: LayoutBuilder( 29 | builder: (BuildContext context, BoxConstraints constraints) { 30 | return Container( 31 | width: 100, 32 | height: 100, 33 | color: Colors.blue, 34 | child: const Text('test1'), 35 | ); 36 | }, 37 | ), 38 | ); 39 | 40 | final styledToast = StyledToast( 41 | //You have to set this parameters to your locale 42 | textStyle: textStyle, 43 | backgroundColor: backgroundColor, 44 | borderRadius: borderRadius, 45 | textPadding: textPadding, 46 | toastAnimation: toastAnimation, 47 | reverseAnimation: reverseAnimation, 48 | startOffset: startOffset, 49 | reverseEndOffset: reverseEndOffset, 50 | duration: duration, 51 | animDuration: animDuration, 52 | alignment: alignment, 53 | toastPositions: toastPositions, 54 | curve: curve, 55 | reverseCurve: reverseCurve, 56 | dismissOtherOnShow: dismissOtherOnShow, 57 | locale: const Locale('en', 'US'), 58 | fullWidth: fullWidth, 59 | isHideKeyboard: isHideKeyboard, 60 | isIgnoring: isIgnoring, 61 | child: child, 62 | ); 63 | await tester.pumpWidget(styledToast); 64 | await tester.pump(const Duration(milliseconds: 1000)); 65 | expect(styledToast.locale, const Locale('en', 'US')); 66 | expect(styledToast.textStyle, 67 | const TextStyle(fontSize: 16.0, color: Colors.white)); 68 | expect(styledToast.backgroundColor, const Color(0x99000000)); 69 | expect(styledToast.borderRadius, BorderRadius.circular(5.0)); 70 | expect(styledToast.textPadding, 71 | const EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0)); 72 | expect(styledToast.toastAnimation, StyledToastAnimation.size); 73 | expect(styledToast.reverseAnimation, StyledToastAnimation.size); 74 | expect(styledToast.startOffset, const Offset(0.0, -1.0)); 75 | expect(styledToast.reverseEndOffset, const Offset(0.0, -1.0)); 76 | expect(styledToast.duration, const Duration(seconds: 4)); 77 | expect(styledToast.animDuration, const Duration(seconds: 1)); 78 | expect(styledToast.alignment, Alignment.center); 79 | expect(styledToast.toastPositions, StyledToastPosition.center); 80 | expect(styledToast.curve, Curves.fastOutSlowIn); 81 | expect(styledToast.reverseCurve, Curves.fastOutSlowIn); 82 | expect(styledToast.dismissOtherOnShow, true); 83 | expect(styledToast.fullWidth, false); 84 | expect(styledToast.isHideKeyboard, false); 85 | expect(styledToast.isIgnoring, true); 86 | expect(find.text('test1'), findsOneWidget); 87 | }); 88 | }); 89 | 90 | group('show a toast', () { 91 | testWidgets('showToast', (WidgetTester tester) async { 92 | final GlobalKey key = GlobalKey(); 93 | final testAppWidget = TestAppWidget(key: key); 94 | await tester.pumpWidget(testAppWidget); 95 | showToast( 96 | 'toast0', 97 | duration: const Duration(seconds: 4), 98 | animDuration: const Duration(seconds: 2), 99 | position: StyledToastPosition.bottom, 100 | textStyle: TextStyle(fontSize: 20, color: Colors.green[700]), 101 | textPadding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20), 102 | toastHorizontalMargin: 40, 103 | backgroundColor: Colors.black45, 104 | borderRadius: BorderRadius.circular(20), 105 | shapeBorder: RoundedRectangleBorder( 106 | side: const BorderSide( 107 | color: Colors.blue, width: 1.0, style: BorderStyle.solid), 108 | borderRadius: BorderRadius.circular(5)), 109 | onDismiss: () {}, 110 | textDirection: TextDirection.ltr, 111 | dismissOtherToast: true, 112 | animation: StyledToastAnimation.slideFromBottom, 113 | reverseAnimation: StyledToastAnimation.slideToLeftFade, 114 | alignment: Alignment.center, 115 | axis: Axis.horizontal, 116 | startOffset: const Offset(0, 1.0), 117 | endOffset: const Offset(0, 0), 118 | reverseStartOffset: const Offset(0, 0), 119 | reverseEndOffset: const Offset(-1, 0), 120 | textAlign: TextAlign.center, 121 | curve: Curves.decelerate, 122 | reverseCurve: Curves.linear, 123 | fullWidth: false, 124 | isHideKeyboard: true, 125 | isIgnoring: true, 126 | ); 127 | await tester.pump(const Duration(milliseconds: 100)); 128 | 129 | expect(find.text('toast0'), findsOneWidget); 130 | 131 | await tester.pump(const Duration(seconds: 4)); 132 | 133 | expect(find.text('toast0'), findsNothing); 134 | }); 135 | 136 | testWidgets('showToastWidget', (WidgetTester tester) async { 137 | final GlobalKey key = GlobalKey(); 138 | final testAppWidget = TestAppWidget(key: key); 139 | await tester.pumpWidget(testAppWidget); 140 | showToastWidget( 141 | const Text('custom widget'), 142 | duration: const Duration(seconds: 4), 143 | animDuration: const Duration(seconds: 2), 144 | position: StyledToastPosition.bottom, 145 | onDismiss: () {}, 146 | textDirection: TextDirection.ltr, 147 | dismissOtherToast: true, 148 | animation: StyledToastAnimation.slideFromBottom, 149 | reverseAnimation: StyledToastAnimation.slideToLeftFade, 150 | alignment: Alignment.center, 151 | axis: Axis.horizontal, 152 | startOffset: const Offset(0, 1.0), 153 | endOffset: const Offset(0, 0), 154 | reverseStartOffset: const Offset(0, 0), 155 | reverseEndOffset: const Offset(-1, 0), 156 | curve: Curves.decelerate, 157 | reverseCurve: Curves.linear, 158 | isHideKeyboard: true, 159 | isIgnoring: true, 160 | ); 161 | await tester.pump(const Duration(milliseconds: 100)); 162 | 163 | expect(find.text('custom widget'), findsOneWidget); 164 | 165 | await tester.pump(const Duration(seconds: 4)); 166 | 167 | expect(find.text('custom widget'), findsNothing); 168 | }); 169 | 170 | testWidgets('CustomAnimation', (WidgetTester tester) async { 171 | final GlobalKey key = GlobalKey(); 172 | final testAppWidget = TestAppWidget(key: key); 173 | await tester.pumpWidget(testAppWidget); 174 | showToastWidget( 175 | const Text('custom widget'), 176 | duration: const Duration(seconds: 4), 177 | animDuration: const Duration(seconds: 2), 178 | position: StyledToastPosition.bottom, 179 | onDismiss: () {}, 180 | textDirection: TextDirection.ltr, 181 | dismissOtherToast: true, 182 | animation: StyledToastAnimation.slideFromBottom, 183 | reverseAnimation: StyledToastAnimation.slideToLeftFade, 184 | alignment: Alignment.center, 185 | axis: Axis.horizontal, 186 | startOffset: const Offset(0, 1.0), 187 | endOffset: const Offset(0, 0), 188 | reverseStartOffset: const Offset(0, 0), 189 | reverseEndOffset: const Offset(-1, 0), 190 | curve: Curves.decelerate, 191 | reverseCurve: Curves.linear, 192 | isHideKeyboard: true, 193 | isIgnoring: true, 194 | ); 195 | await tester.pump(const Duration(milliseconds: 100)); 196 | 197 | expect(find.text('custom widget'), findsOneWidget); 198 | 199 | await tester.pump(const Duration(seconds: 4)); 200 | 201 | expect(find.text('custom widget'), findsNothing); 202 | }); 203 | }); 204 | } 205 | 206 | class TestAppWidget extends StatefulWidget { 207 | final OverlayEntry? overlayEntry; 208 | 209 | const TestAppWidget({super.key, this.overlayEntry}); 210 | 211 | @override 212 | TestAppWidgetState createState() => TestAppWidgetState(); 213 | } 214 | 215 | class TestAppWidgetState extends State { 216 | late BuildContext _context; 217 | 218 | void insertEntry() { 219 | if (widget.overlayEntry != null) { 220 | Overlay.of(_context).insert(widget.overlayEntry!); 221 | } 222 | } 223 | 224 | StyledToastTheme? getStyleToastTheme() { 225 | return StyledToastTheme.maybeOf(_context); 226 | } 227 | 228 | @override 229 | Widget build(BuildContext context) { 230 | const appTitle = 'Styled Toast Example'; 231 | return StyledToast( 232 | textStyle: const TextStyle(fontSize: 16.0, color: Colors.white), 233 | backgroundColor: const Color(0x99000000), 234 | borderRadius: const BorderRadius.all(Radius.circular(5.0)), 235 | textPadding: const EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0), 236 | toastAnimation: StyledToastAnimation.size, 237 | reverseAnimation: StyledToastAnimation.size, 238 | startOffset: const Offset(0.0, -1.0), 239 | reverseEndOffset: const Offset(0.0, -1.0), 240 | duration: const Duration(seconds: 4), 241 | animDuration: const Duration(seconds: 1), 242 | alignment: Alignment.center, 243 | toastPositions: StyledToastPosition.center, 244 | curve: Curves.fastOutSlowIn, 245 | reverseCurve: Curves.fastOutSlowIn, 246 | dismissOtherOnShow: true, 247 | locale: const Locale('en', 'US'), 248 | fullWidth: false, 249 | isHideKeyboard: false, 250 | isIgnoring: true, 251 | child: MaterialApp( 252 | title: appTitle, 253 | home: LayoutBuilder( 254 | builder: (BuildContext context, BoxConstraints constraints) { 255 | _context = context; 256 | return Container( 257 | color: Colors.blue, 258 | ); 259 | }, 260 | ), 261 | ), 262 | ); 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /test/styled_toast_theme_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_styled_toast/flutter_styled_toast.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | void main() { 6 | group('StyledToastTheme', () { 7 | testWidgets('Create StyleToastTheme', (WidgetTester tester) async { 8 | const textStyle = TextStyle(fontSize: 16.0, color: Colors.white); 9 | const backgroundColor = Color(0x99000000); 10 | final borderRadius = BorderRadius.circular(5.0); 11 | const textPadding = 12 | EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0); 13 | const toastAnimation = StyledToastAnimation.size; 14 | const reverseAnimation = StyledToastAnimation.size; 15 | const startOffset = Offset(0.0, -1.0); 16 | const reverseEndOffset = Offset(0.0, -1.0); 17 | const duration = Duration(seconds: 4); 18 | const animDuration = Duration(seconds: 1); 19 | const alignment = Alignment.center; 20 | const toastPositions = StyledToastPosition.center; 21 | const curve = Curves.fastOutSlowIn; 22 | const reverseCurve = Curves.fastOutSlowIn; 23 | const dismissOtherOnShow = true; 24 | const fullWidth = false; 25 | const isHideKeyboard = false; 26 | const isIgnoring = true; 27 | final child = MaterialApp( 28 | home: LayoutBuilder( 29 | builder: (BuildContext context, BoxConstraints constraints) { 30 | return Container( 31 | width: 100, 32 | height: 100, 33 | color: Colors.blue, 34 | child: const Text('test1'), 35 | ); 36 | }, 37 | ), 38 | ); 39 | 40 | final styledToastTheme = StyledToastTheme( 41 | //You have to set this parameters to your locale 42 | textStyle: textStyle, 43 | backgroundColor: backgroundColor, 44 | borderRadius: borderRadius, 45 | textPadding: textPadding, 46 | toastAnimation: toastAnimation, 47 | reverseAnimation: reverseAnimation, 48 | startOffset: startOffset, 49 | reverseEndOffset: reverseEndOffset, 50 | duration: duration, 51 | animDuration: animDuration, 52 | alignment: alignment, 53 | toastPositions: toastPositions, 54 | curve: curve, 55 | reverseCurve: reverseCurve, 56 | dismissOtherOnShow: dismissOtherOnShow, 57 | fullWidth: fullWidth, 58 | isHideKeyboard: isHideKeyboard, 59 | isIgnoring: isIgnoring, 60 | child: child, 61 | ); 62 | await tester.pumpWidget(styledToastTheme); 63 | await tester.pump(const Duration(milliseconds: 1000)); 64 | expect(styledToastTheme.textStyle, 65 | const TextStyle(fontSize: 16.0, color: Colors.white)); 66 | expect(styledToastTheme.backgroundColor, const Color(0x99000000)); 67 | expect(styledToastTheme.borderRadius, BorderRadius.circular(5.0)); 68 | expect(styledToastTheme.textPadding, 69 | const EdgeInsets.symmetric(horizontal: 17.0, vertical: 10.0)); 70 | expect(styledToastTheme.toastAnimation, StyledToastAnimation.size); 71 | expect(styledToastTheme.reverseAnimation, StyledToastAnimation.size); 72 | expect(styledToastTheme.startOffset, const Offset(0.0, -1.0)); 73 | expect(styledToastTheme.reverseEndOffset, const Offset(0.0, -1.0)); 74 | expect(styledToastTheme.duration, const Duration(seconds: 4)); 75 | expect(styledToastTheme.animDuration, const Duration(seconds: 1)); 76 | expect(styledToastTheme.alignment, Alignment.center); 77 | expect(styledToastTheme.toastPositions, StyledToastPosition.center); 78 | expect(styledToastTheme.curve, Curves.fastOutSlowIn); 79 | expect(styledToastTheme.reverseCurve, Curves.fastOutSlowIn); 80 | expect(styledToastTheme.dismissOtherOnShow, true); 81 | expect(styledToastTheme.fullWidth, false); 82 | expect(styledToastTheme.isHideKeyboard, false); 83 | expect(styledToastTheme.isIgnoring, true); 84 | expect(find.text('test1'), findsOneWidget); 85 | }); 86 | }); 87 | } 88 | --------------------------------------------------------------------------------