├── .github ├── FUNDING.yml ├── stale.yml └── workflows │ ├── checker.yml │ ├── pub_dry_run.yml │ ├── pub_publish.yml │ └── pub_publish_manually.yml ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── CODEOWNERS ├── LICENSE ├── README-ZH.md ├── README.md ├── analysis_options.yaml ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ff_annotation_route_commands ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── .last_build_id │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── example_route.dart │ ├── example_routes.dart │ ├── main.dart │ └── pages │ │ ├── like_button_demo.dart │ │ └── main_page.dart ├── macos │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ └── app_icon_64.png │ │ ├── Base.lproj │ │ └── MainMenu.xib │ │ ├── Configs │ │ ├── AppInfo.xcconfig │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── Warnings.xcconfig │ │ ├── DebugProfile.entitlements │ │ ├── Info.plist │ │ ├── MainFlutterWindow.swift │ │ └── Release.entitlements ├── pubspec.yaml ├── test │ └── widget_test.dart └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ └── Icon-512.png │ ├── index.html │ └── manifest.json ├── lib ├── like_button.dart └── src │ ├── like_button.dart │ ├── painter │ ├── bubbles_painter.dart │ └── circle_painter.dart │ └── utils │ ├── like_button_model.dart │ ├── like_button_typedef.dart │ └── like_button_util.dart └── pubspec.yaml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | #github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | #patreon: # Replace with a single Patreon username 5 | #open_collective: # Replace with a single Open Collective username 6 | #ko_fi: # Replace with a single Ko-fi username 7 | #tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | #community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | #liberapay: zmtzawqlp 10 | #issuehunt: # Replace with a single IssueHunt username 11 | #otechie: # Replace with a single Otechie username 12 | custom: http://zmtzawqlp.gitee.io/my_images/images/qrcode.png 13 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: true -------------------------------------------------------------------------------- /.github/workflows/checker.yml: -------------------------------------------------------------------------------- 1 | name: No Free usage issue checker 2 | 3 | on: 4 | issues: 5 | types: [opened, reopened] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Check issue actor 15 | uses: ./ 16 | with: 17 | repo: $GITHUB_REPOSITORY 18 | user: $GITHUB_ACTOR 19 | token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/pub_dry_run.yml: -------------------------------------------------------------------------------- 1 | name: Pub Publish dry run 2 | 3 | on: [push] 4 | 5 | jobs: 6 | publish: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v1 13 | - name: Publish 14 | uses: sakebook/actions-flutter-pub-publisher@v1.3.0 15 | with: 16 | credential: ${{ secrets.CREDENTIAL_JSON }} 17 | flutter_package: true 18 | skip_test: true 19 | dry_run: true 20 | -------------------------------------------------------------------------------- /.github/workflows/pub_publish.yml: -------------------------------------------------------------------------------- 1 | name: Pub Publish plugin 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v1 15 | - name: Publish 16 | uses: sakebook/actions-flutter-pub-publisher@v1.3.0 17 | with: 18 | credential: ${{ secrets.CREDENTIAL_JSON }} 19 | flutter_package: true 20 | skip_test: true 21 | dry_run: false 22 | -------------------------------------------------------------------------------- /.github/workflows/pub_publish_manually.yml: -------------------------------------------------------------------------------- 1 | name: Pub Publish plugin 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | publish: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v1 13 | - name: Publish 14 | uses: sakebook/actions-flutter-pub-publisher@v1.3.0 15 | with: 16 | credential: ${{ secrets.CREDENTIAL_JSON }} 17 | flutter_package: true 18 | skip_test: true 19 | dry_run: false 20 | -------------------------------------------------------------------------------- /.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 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | 72 | .packages 73 | pubspec.lock -------------------------------------------------------------------------------- /.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: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.1.0 2 | 3 | * Externally control animation using isLiked flag 4 | 5 | ## 2.0.5 6 | 7 | * Add postFrameCallback to support start animation at first time(#65) 8 | 9 | ## 2.0.4 10 | 11 | * Fix issue that Number reversed when using RTL localization 12 | 13 | ## 2.0.3 14 | 15 | * Fix issue that LikeButtonTapCallback result can't be null 16 | 17 | ## 2.0.2 18 | 19 | * Fix issue that Bubble animation is cropped #50 20 | 21 | ## 2.0.1 22 | 23 | * Format dart 24 | 25 | ## 2.0.0 26 | 27 | * Support null-safety 28 | 29 | ## 1.0.4 30 | 31 | * Fix animation stop when setstate 32 | 33 | ## 1.0.3 34 | 35 | * Fix readme error 36 | 37 | ## 1.0.2 38 | 39 | * Add stale.yml 40 | 41 | ## 1.0.1 42 | 43 | * Fix the error of bubbles_painter.dart. 44 | 45 | ## 1.0.0 46 | 47 | * Fix analysis_options 48 | * Breaking change: add likeCount for CountDecoration call back 49 | * Public LikeButtonState and onTap 50 | 51 | ## 0.2.0 52 | 53 | * Support Flutter Web 54 | * Add web demo 55 | 56 | ## 0.1.9 57 | 58 | * Change postion to CountPostion, support top/bottom 59 | * Add CountDecoration to custom count widget 60 | 61 | ## 0.1.8 62 | 63 | * Add padding parameter for LikeButton 64 | * Change bubbles' position to make them more clear. 65 | 66 | ## 0.1.7 67 | 68 | * Feature: 69 | Add postion(left,right) support for like count widget 70 | 71 | ## 0.1.6 72 | 73 | * Issue: fix likeCount/isLiked are not updated when rebuild. 74 | 75 | ## 0.1.4 76 | 77 | * Support to always show like animation and increase like count by setting isLiked to null. 78 | 79 | ## 0.1.3 80 | 81 | * Clip rect before padding(like count) 82 | 83 | ## 0.1.2 84 | 85 | * Add OpacityAnimation for LikeCountAnimationType.part 86 | 87 | ## 0.1.1 88 | 89 | * Update readme 90 | * Change dotSize to bubblesSize 91 | 92 | ## 0.1.0 93 | 94 | * First Release 95 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @zmtzawqlp 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 zmtzawqlp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README-ZH.md: -------------------------------------------------------------------------------- 1 | # like_button 2 | 3 | [![pub package](https://img.shields.io/pub/v/like_button.svg)](https://pub.dartlang.org/packages/like_button) [![GitHub stars](https://img.shields.io/github/stars/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/stargazers) [![GitHub forks](https://img.shields.io/github/forks/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/network) [![GitHub license](https://img.shields.io/github/license/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/blob/master/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/issues) ![FlutterCandies QQ 群](https://img.shields.io/badge/dynamic/yaml?url=https%3A%2F%2Fraw.githubusercontent.com%2Ffluttercandies%2F.github%2Frefs%2Fheads%2Fmain%2Fdata.yml&query=%24.qq_group_number&label=QQ%E7%BE%A4&logo=qq&color=1DACE8) 4 | 5 | 文档语言: [English](README.md) | [中文简体](README-ZH.md) 6 | 7 | Like Button 支持推特点赞效果和喜欢数量动画的Flutter库. 8 | 9 | 感谢 [jd-alexander](https://github.com/jd-alexander/LikeButton) and [吉原拉面](https://github.com/yumi0629/FlutterUI/tree/master/lib/likebutton) 对点赞动画的原理的开源。 10 | 11 | [Flutter 仿掘金推特点赞按钮](https://juejin.im/post/5cee3b43e51d45773f2e8ed7) 12 | 13 | [Web Demo for LikeButton](https://fluttercandies.github.io/like_button/) 14 | 15 | ![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/like_button/like_button.gif) 16 | 17 | - [like_button](#likebutton) 18 | - [如何使用.](#%e5%a6%82%e4%bd%95%e4%bd%bf%e7%94%a8) 19 | - [什么时候去请求服务改变状态](#%e4%bb%80%e4%b9%88%e6%97%b6%e5%80%99%e5%8e%bb%e8%af%b7%e6%b1%82%e6%9c%8d%e5%8a%a1%e6%94%b9%e5%8f%98%e7%8a%b6%e6%80%81) 20 | - [参数](#%e5%8f%82%e6%95%b0) 21 | 22 | ## 如何使用. 23 | 24 | 默认效果是Icons.favorite 25 | ```dart 26 | LikeButton(), 27 | ``` 28 | 29 | 你可以自定义一些效果,比如颜色,比如喜欢数量显示, 30 | ```dart 31 | LikeButton( 32 | size: buttonSize, 33 | circleColor: 34 | CircleColor(start: Color(0xff00ddff), end: Color(0xff0099cc)), 35 | bubblesColor: BubblesColor( 36 | dotPrimaryColor: Color(0xff33b5e5), 37 | dotSecondaryColor: Color(0xff0099cc), 38 | ), 39 | likeBuilder: (bool isLiked) { 40 | return Icon( 41 | Icons.home, 42 | color: isLiked ? Colors.deepPurpleAccent : Colors.grey, 43 | size: buttonSize, 44 | ); 45 | }, 46 | likeCount: 665, 47 | countBuilder: (int count, bool isLiked, String text) { 48 | var color = isLiked ? Colors.deepPurpleAccent : Colors.grey; 49 | Widget result; 50 | if (count == 0) { 51 | result = Text( 52 | "love", 53 | style: TextStyle(color: color), 54 | ); 55 | } else 56 | result = Text( 57 | text, 58 | style: TextStyle(color: color), 59 | ); 60 | return result; 61 | }, 62 | ), 63 | ``` 64 | 65 | ## 什么时候去请求服务改变状态 66 | ```dart 67 | LikeButton( 68 | onTap: onLikeButtonTapped, 69 | ), 70 | ``` 71 | 这是一个异步回调,你可以等待服务返回之后再改变状态。也可以先改变状态,请求失败之后重置回状态 72 | 73 | ```dart 74 | Future onLikeButtonTapped(bool isLiked) async{ 75 | /// send your request here 76 | // final bool success= await sendRequest(); 77 | 78 | /// if failed, you can do nothing 79 | // return success? !isLiked:isLiked; 80 | 81 | return !isLiked; 82 | } 83 | ``` 84 | 85 | ## 参数 86 | | 参数 | 描述 | 默认 | 87 | | -------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 88 | | size | like Widget的大小 | 30.0 | 89 | | animationDuration | like widget动画的时间 | const Duration(milliseconds: 1000) | 90 | | bubblesSize | 动画时候的泡泡的大小 | size * 2.0 | 91 | | bubblesColor | 动画时候的泡泡的颜色,需要设置4种 | const BubblesColor(dotPrimaryColor: const Color(0xFFFFC107),dotSecondaryColor: const Color(0xFFFF9800),dotThirdColor: const Color(0xFFFF5722),dotLastColor: const Color(0xFFF44336),) | 92 | | circleSize | 动画时候的圈的最大大小 | size * 0.8 | 93 | | circleColor | 动画时候的圈的颜色,需要设置2种 | const CircleColor(start: const Color(0xFFFF5722), end: const Color(0xFFFFC107) | 94 | | onTap | 点击时候的回调,你可以在里面请求服务改变状态 | | 95 | | isLiked | 是否喜欢。如果设置null的话,将会一直有动画,而且喜欢数量一直增长 | false | 96 | | likeCount | 喜欢数量。如果为null的话,不显示 | null | 97 | | mainAxisAlignment | MainAxisAlignment ,like widget和like count widget是放在一个Row里面的,对应Row的mainAxisAlignment属性 | MainAxisAlignment.center | 98 | | likeBuilder | like widget的创建回调 | null | 99 | | countBuilder | like count widget的创建回调 | null | 100 | | likeCountAnimationDuration | 喜欢数量变化动画的时间 | const Duration(milliseconds: 500) | 101 | | likeCountAnimationType | 喜欢数量动画的类型(none,part,all)。没有动画;只动画改变的部分;全部部分 | LikeCountAnimationType.part | 102 | | likeCountPadding | like count widget 跟 like widget的间隔 | const EdgeInsets.only(left: 3.0) | 103 | | countPostion | top,right,bottom,left. count的位置(上下左右) | CountPostion.right | 104 | | countDecoration | count 的修饰器,你可以通过它为count增加其他文字或者效果 | null | | 105 | | postFrameCallback | 第一帧回调返回 LikeButtonState | null | 106 | 107 | ## ☕️Buy me a coffee 108 | 109 | ![img](http://zmtzawqlp.gitee.io/my_images/images/qrcode.png) 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # like_button 2 | 3 | [![pub package](https://img.shields.io/pub/v/like_button.svg)](https://pub.dartlang.org/packages/like_button) [![GitHub stars](https://img.shields.io/github/stars/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/stargazers) [![GitHub forks](https://img.shields.io/github/forks/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/network) [![GitHub license](https://img.shields.io/github/license/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/blob/master/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/fluttercandies/like_button)](https://github.com/fluttercandies/like_button/issues) ![FlutterCandies QQ 群](https://img.shields.io/badge/dynamic/yaml?url=https%3A%2F%2Fraw.githubusercontent.com%2Ffluttercandies%2F.github%2Frefs%2Fheads%2Fmain%2Fdata.yml&query=%24.qq_group_number&label=QQ%E7%BE%A4&logo=qq&color=1DACE8) 4 | 5 | Language: [English](README.md) | [中文简体](README-ZH.md) 6 | 7 | Like Button is a flutter library that allows you to create a button with animation effects similar to Twitter's heart when you like something and animation effects to increase like count. 8 | 9 | Reference codes from [jd-alexander](https://github.com/jd-alexander/LikeButton) and [吉原拉面](https://github.com/yumi0629/FlutterUI/tree/master/lib/likebutton) ,thank them for open source code. 10 | 11 | 12 | [Web Demo for LikeButton](https://fluttercandies.github.io/like_button/) 13 | 14 | ![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/like_button/like_button.gif) 15 | 16 | - [like_button](#like_button) 17 | - [How to use it.](#how-to-use-it) 18 | - [The time to send your request](#the-time-to-send-your-request) 19 | - [parameters](#parameters) 20 | 21 | ## How to use it. 22 | 23 | the default effects is Icons.favorite 24 | ```dart 25 | LikeButton(), 26 | ``` 27 | 28 | and you can also define custom effects. 29 | ```dart 30 | LikeButton( 31 | size: buttonSize, 32 | circleColor: 33 | CircleColor(start: Color(0xff00ddff), end: Color(0xff0099cc)), 34 | bubblesColor: BubblesColor( 35 | dotPrimaryColor: Color(0xff33b5e5), 36 | dotSecondaryColor: Color(0xff0099cc), 37 | ), 38 | likeBuilder: (bool isLiked) { 39 | return Icon( 40 | Icons.home, 41 | color: isLiked ? Colors.deepPurpleAccent : Colors.grey, 42 | size: buttonSize, 43 | ); 44 | }, 45 | likeCount: 665, 46 | countBuilder: (int count, bool isLiked, String text) { 47 | var color = isLiked ? Colors.deepPurpleAccent : Colors.grey; 48 | Widget result; 49 | if (count == 0) { 50 | result = Text( 51 | "love", 52 | style: TextStyle(color: color), 53 | ); 54 | } else 55 | result = Text( 56 | text, 57 | style: TextStyle(color: color), 58 | ); 59 | return result; 60 | }, 61 | ), 62 | ``` 63 | 64 | ## The time to send your request 65 | ```dart 66 | LikeButton( 67 | onTap: onLikeButtonTapped, 68 | ), 69 | ``` 70 | 71 | ```dart 72 | Future onLikeButtonTapped(bool isLiked) async{ 73 | /// send your request here 74 | // final bool success= await sendRequest(); 75 | 76 | /// if failed, you can do nothing 77 | // return success? !isLiked:isLiked; 78 | 79 | return !isLiked; 80 | } 81 | ``` 82 | 83 | ## parameters 84 | | parameter | description | default | 85 | | -------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 86 | | size | size of like widget | 30.0 | 87 | | animationDuration | animation duration to change isLiked state | const Duration(milliseconds: 1000) | 88 | | bubblesSize | total size of bubbles | size * 2.0 | 89 | | bubblesColor | colors of bubbles | const BubblesColor(dotPrimaryColor: const Color(0xFFFFC107),dotSecondaryColor: const Color(0xFFFF9800),dotThirdColor: const Color(0xFFFF5722),dotLastColor: const Color(0xFFF44336),) | 90 | | circleSize | final size of circle | size * 0.8 | 91 | | circleColor | colors of circle | const CircleColor(start: const Color(0xFFFF5722), end: const Color(0xFFFFC107) | 92 | | onTap | tap call back of like button,you can handle your request in this call back | | 93 | | isLiked | whether it is liked(if it's null, always show like animation and increase like count) | false | 94 | | likeCount | if null, will not show) | null | 95 | | mainAxisAlignment | MainAxisAlignment for like button | MainAxisAlignment.center | 96 | | likeBuilder | builder to create like widget | null | 97 | | countBuilder | builder to create like count widget | null | 98 | | likeCountAnimationDuration | animation duration to change like count | const Duration(milliseconds: 500) | 99 | | likeCountAnimationType | animation type to change like count(none,part,all) | LikeCountAnimationType.part | 100 | | likeCountPadding | padding for like count widget | const EdgeInsets.only(left: 3.0) | 101 | | countPostion | top,right,bottom,left of like button widget | CountPostion.right | 102 | | countDecoration | decoration of like count widget | null | 103 | | postFrameCallback | call back of first frame with LikeButtonState | null | 104 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Specify analysis options. 2 | # 3 | # Until there are meta linter rules, each desired lint must be explicitly enabled. 4 | # See: https://github.com/dart-lang/linter/issues/288 5 | # 6 | # For a list of lints, see: http://dart-lang.github.io/linter/lints/ 7 | # See the configuration guide for more 8 | # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer 9 | # 10 | # There are other similar analysis options files in the flutter repos, 11 | # which should be kept in sync with this file: 12 | # 13 | # - analysis_options.yaml (this file) 14 | # - packages/flutter/lib/analysis_options_user.yaml 15 | # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml 16 | # - https://github.com/flutter/engine/blob/master/analysis_options.yaml 17 | # 18 | # This file contains the analysis options used by Flutter tools, such as IntelliJ, 19 | # Android Studio, and the `flutter analyze` command. 20 | 21 | analyzer: 22 | strong-mode: 23 | implicit-casts: false 24 | implicit-dynamic: false 25 | errors: 26 | # treat missing required parameters as a warning (not a hint) 27 | missing_required_param: warning 28 | # treat missing returns as a warning (not a hint) 29 | missing_return: warning 30 | # allow having TODOs in the code 31 | todo: ignore 32 | # Ignore analyzer hints for updating pubspecs when using Future or 33 | # Stream and not importing dart:async 34 | # Please see https://github.com/flutter/flutter/pull/24528 for details. 35 | sdk_version_async_exported_from_core: ignore 36 | # exclude: 37 | # - "bin/cache/**" 38 | # # the following two are relative to the stocks example and the flutter package respectively 39 | # # see https://github.com/dart-lang/sdk/issues/28463 40 | # - "lib/i18n/messages_*.dart" 41 | # - "lib/src/http/**" 42 | 43 | linter: 44 | rules: 45 | # these rules are documented on and in the same order as 46 | # the Dart Lint rules page to make maintenance easier 47 | # https://github.com/dart-lang/linter/blob/master/example/all.yaml 48 | - always_declare_return_types 49 | - always_put_control_body_on_new_line 50 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 51 | - always_require_non_null_named_parameters 52 | - always_specify_types 53 | - annotate_overrides 54 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types 55 | # - avoid_as # required for implicit-casts: true 56 | - avoid_bool_literals_in_conditional_expressions 57 | # - avoid_catches_without_on_clauses # we do this commonly 58 | # - avoid_catching_errors # we do this commonly 59 | - avoid_classes_with_only_static_members 60 | # - avoid_double_and_int_checks # only useful when targeting JS runtime 61 | - avoid_empty_else 62 | # - avoid_equals_and_hash_code_on_mutable_classes # not yet tested 63 | - avoid_field_initializers_in_const_classes 64 | - avoid_function_literals_in_foreach_calls 65 | # - avoid_implementing_value_types # not yet tested 66 | - avoid_init_to_null 67 | # - avoid_js_rounded_ints # only useful when targeting JS runtime 68 | - avoid_null_checks_in_equality_operators 69 | # - avoid_positional_boolean_parameters # not yet tested 70 | # - avoid_print # not yet tested 71 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 72 | # - avoid_redundant_argument_values # not yet tested 73 | - avoid_relative_lib_imports 74 | - avoid_renaming_method_parameters 75 | - avoid_return_types_on_setters 76 | # - avoid_returning_null # there are plenty of valid reasons to return null 77 | # - avoid_returning_null_for_future # not yet tested 78 | - avoid_returning_null_for_void 79 | # - avoid_returning_this # there are plenty of valid reasons to return this 80 | # - avoid_setters_without_getters # not yet tested 81 | # - avoid_shadowing_type_parameters # not yet tested 82 | - avoid_single_cascade_in_expression_statements 83 | - avoid_slow_async_io 84 | - avoid_types_as_parameter_names 85 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types 86 | # - avoid_unnecessary_containers # not yet tested 87 | - avoid_unused_constructor_parameters 88 | - avoid_void_async 89 | # - avoid_web_libraries_in_flutter # not yet tested 90 | - await_only_futures 91 | - camel_case_extensions 92 | - camel_case_types 93 | - cancel_subscriptions 94 | # - cascade_invocations # not yet tested 95 | # - close_sinks # not reliable enough 96 | # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 97 | # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 98 | - control_flow_in_finally 99 | # - curly_braces_in_flow_control_structures # not yet tested 100 | # - diagnostic_describe_all_properties # not yet tested 101 | - directives_ordering 102 | - empty_catches 103 | - empty_constructor_bodies 104 | - empty_statements 105 | # - file_names # not yet tested 106 | - flutter_style_todos 107 | - hash_and_equals 108 | - implementation_imports 109 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 110 | - iterable_contains_unrelated_type 111 | # - join_return_with_assignment # not yet tested 112 | - library_names 113 | - library_prefixes 114 | # - lines_longer_than_80_chars # not yet tested 115 | - list_remove_unrelated_type 116 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 117 | # - missing_whitespace_between_adjacent_strings # not yet tested 118 | - no_adjacent_strings_in_list 119 | - no_duplicate_case_values 120 | # - no_logic_in_create_state # not yet tested 121 | # - no_runtimeType_toString # not yet tested 122 | - non_constant_identifier_names 123 | # - null_closures # not yet tested 124 | # - omit_local_variable_types # opposite of always_specify_types 125 | # - one_member_abstracts # too many false positives 126 | # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 127 | - overridden_fields 128 | - package_api_docs 129 | - package_names 130 | - package_prefixed_library_names 131 | # - parameter_assignments # we do this commonly 132 | - prefer_adjacent_string_concatenation 133 | - prefer_asserts_in_initializer_lists 134 | # - prefer_asserts_with_message # not yet tested 135 | - prefer_collection_literals 136 | - prefer_conditional_assignment 137 | - prefer_const_constructors 138 | - prefer_const_constructors_in_immutables 139 | - prefer_const_declarations 140 | - prefer_const_literals_to_create_immutables 141 | # - prefer_constructors_over_static_methods # not yet tested 142 | - prefer_contains 143 | # - prefer_double_quotes # opposite of prefer_single_quotes 144 | - prefer_equal_for_default_values 145 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 146 | - prefer_final_fields 147 | - prefer_final_in_for_each 148 | - prefer_final_locals 149 | - prefer_for_elements_to_map_fromIterable 150 | - prefer_foreach 151 | # - prefer_function_declarations_over_variables # not yet tested 152 | - prefer_generic_function_type_aliases 153 | - prefer_if_elements_to_conditional_expressions 154 | - prefer_if_null_operators 155 | - prefer_initializing_formals 156 | - prefer_inlined_adds 157 | # - prefer_int_literals # not yet tested 158 | # - prefer_interpolation_to_compose_strings # not yet tested 159 | - prefer_is_empty 160 | - prefer_is_not_empty 161 | - prefer_is_not_operator 162 | - prefer_iterable_whereType 163 | # - prefer_mixin # https://github.com/dart-lang/language/issues/32 164 | # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 165 | # - prefer_relative_imports # not yet tested 166 | - prefer_single_quotes 167 | - prefer_spread_collections 168 | - prefer_typing_uninitialized_variables 169 | - prefer_void_to_null 170 | # - provide_deprecation_message # not yet tested 171 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 172 | - recursive_getters 173 | - slash_for_doc_comments 174 | # - sort_child_properties_last # not yet tested 175 | - sort_constructors_first 176 | - sort_pub_dependencies 177 | - sort_unnamed_constructors_first 178 | - test_types_in_equals 179 | - throw_in_finally 180 | # - type_annotate_public_apis # subset of always_specify_types 181 | - type_init_formals 182 | # - unawaited_futures # too many false positives 183 | # - unnecessary_await_in_return # not yet tested 184 | - unnecessary_brace_in_string_interps 185 | - unnecessary_const 186 | # - unnecessary_final # conflicts with prefer_final_locals 187 | - unnecessary_getters_setters 188 | # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 189 | - unnecessary_new 190 | - unnecessary_null_aware_assignments 191 | - unnecessary_null_in_if_null_operators 192 | - unnecessary_overrides 193 | - unnecessary_parenthesis 194 | - unnecessary_statements 195 | - unnecessary_string_interpolations 196 | - unnecessary_this 197 | - unrelated_type_equality_checks 198 | # - unsafe_html # not yet tested 199 | - use_full_hex_values_for_flutter_colors 200 | # - use_function_type_syntax_for_parameters # not yet tested 201 | # - use_key_in_widget_constructors # not yet tested 202 | - use_rethrow_when_possible 203 | # - use_setters_to_change_properties # not yet tested 204 | # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 205 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 206 | - valid_regexps 207 | - void_checks 208 | -------------------------------------------------------------------------------- /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 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | 72 | .packages 73 | pubspec.lock -------------------------------------------------------------------------------- /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/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 33 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.example" 42 | minSdkVersion 16 43 | targetSdkVersion 33 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 20 | 24 | 28 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.22' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.2.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/ff_annotation_route_commands: -------------------------------------------------------------------------------- 1 | -s -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/.last_build_id: -------------------------------------------------------------------------------- 1 | 00976bdddc79f5c4eea00a6008484130 -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 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 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | FRAMEWORK_SEARCH_PATHS = ( 293 | "$(inherited)", 294 | "$(PROJECT_DIR)/Flutter", 295 | ); 296 | INFOPLIST_FILE = Runner/Info.plist; 297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 298 | LIBRARY_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "$(PROJECT_DIR)/Flutter", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 305 | SWIFT_VERSION = 5.0; 306 | VERSIONING_SYSTEM = "apple-generic"; 307 | }; 308 | name = Profile; 309 | }; 310 | 97C147031CF9000F007C117D /* Debug */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 320 | CLANG_WARN_BOOL_CONVERSION = YES; 321 | CLANG_WARN_COMMA = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_STRICT_PROTOTYPES = YES; 335 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 336 | CLANG_WARN_UNREACHABLE_CODE = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 339 | COPY_PHASE_STRIP = NO; 340 | DEBUG_INFORMATION_FORMAT = dwarf; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | ENABLE_TESTABILITY = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 358 | MTL_ENABLE_DEBUG_INFO = YES; 359 | ONLY_ACTIVE_ARCH = YES; 360 | SDKROOT = iphoneos; 361 | TARGETED_DEVICE_FAMILY = "1,2"; 362 | }; 363 | name = Debug; 364 | }; 365 | 97C147041CF9000F007C117D /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ALWAYS_SEARCH_USER_PATHS = NO; 369 | CLANG_ANALYZER_NONNULL = YES; 370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 371 | CLANG_CXX_LIBRARY = "libc++"; 372 | CLANG_ENABLE_MODULES = YES; 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_EMPTY_BODY = YES; 381 | CLANG_WARN_ENUM_CONVERSION = YES; 382 | CLANG_WARN_INFINITE_RECURSION = YES; 383 | CLANG_WARN_INT_CONVERSION = YES; 384 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 385 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 389 | CLANG_WARN_STRICT_PROTOTYPES = YES; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNREACHABLE_CODE = YES; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 394 | COPY_PHASE_STRIP = NO; 395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 396 | ENABLE_NS_ASSERTIONS = NO; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_NO_COMMON_BLOCKS = YES; 400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 402 | GCC_WARN_UNDECLARED_SELECTOR = YES; 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 404 | GCC_WARN_UNUSED_FUNCTION = YES; 405 | GCC_WARN_UNUSED_VARIABLE = YES; 406 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 407 | MTL_ENABLE_DEBUG_INFO = NO; 408 | SDKROOT = iphoneos; 409 | SUPPORTED_PLATFORMS = iphoneos; 410 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 411 | TARGETED_DEVICE_FAMILY = "1,2"; 412 | VALIDATE_PRODUCT = YES; 413 | }; 414 | name = Release; 415 | }; 416 | 97C147061CF9000F007C117D /* Debug */ = { 417 | isa = XCBuildConfiguration; 418 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 419 | buildSettings = { 420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 421 | CLANG_ENABLE_MODULES = YES; 422 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 423 | ENABLE_BITCODE = NO; 424 | FRAMEWORK_SEARCH_PATHS = ( 425 | "$(inherited)", 426 | "$(PROJECT_DIR)/Flutter", 427 | ); 428 | INFOPLIST_FILE = Runner/Info.plist; 429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 430 | LIBRARY_SEARCH_PATHS = ( 431 | "$(inherited)", 432 | "$(PROJECT_DIR)/Flutter", 433 | ); 434 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 438 | SWIFT_VERSION = 5.0; 439 | VERSIONING_SYSTEM = "apple-generic"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147071CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | CLANG_ENABLE_MODULES = YES; 449 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 450 | ENABLE_BITCODE = NO; 451 | FRAMEWORK_SEARCH_PATHS = ( 452 | "$(inherited)", 453 | "$(PROJECT_DIR)/Flutter", 454 | ); 455 | INFOPLIST_FILE = Runner/Info.plist; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 457 | LIBRARY_SEARCH_PATHS = ( 458 | "$(inherited)", 459 | "$(PROJECT_DIR)/Flutter", 460 | ); 461 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 462 | PRODUCT_NAME = "$(TARGET_NAME)"; 463 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 464 | SWIFT_VERSION = 5.0; 465 | VERSIONING_SYSTEM = "apple-generic"; 466 | }; 467 | name = Release; 468 | }; 469 | /* End XCBuildConfiguration section */ 470 | 471 | /* Begin XCConfigurationList section */ 472 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 97C147031CF9000F007C117D /* Debug */, 476 | 97C147041CF9000F007C117D /* Release */, 477 | 249021D3217E4FDB00AE95B9 /* Profile */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 483 | isa = XCConfigurationList; 484 | buildConfigurations = ( 485 | 97C147061CF9000F007C117D /* Debug */, 486 | 97C147071CF9000F007C117D /* Release */, 487 | 249021D4217E4FDB00AE95B9 /* Profile */, 488 | ); 489 | defaultConfigurationIsVisible = 0; 490 | defaultConfigurationName = Release; 491 | }; 492 | /* End XCConfigurationList section */ 493 | }; 494 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 495 | } 496 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/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/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | 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/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/example_route.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY MANUALLY 2 | // ************************************************************************** 3 | // Auto generated by https://github.com/fluttercandies/ff_annotation_route 4 | // ************************************************************************** 5 | // ignore_for_file: prefer_const_literals_to_create_immutables,unused_local_variable,unused_import 6 | import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; 7 | import 'package:flutter/widgets.dart'; 8 | 9 | import 'pages/like_button_demo.dart'; 10 | import 'pages/main_page.dart'; 11 | 12 | FFRouteSettings getRouteSettings({ 13 | required String name, 14 | Map? arguments, 15 | PageBuilder? notFoundPageBuilder, 16 | }) { 17 | final Map safeArguments = 18 | arguments ?? const {}; 19 | switch (name) { 20 | case 'fluttercandies://LikeButtonDemo': 21 | return FFRouteSettings( 22 | name: name, 23 | arguments: arguments, 24 | builder: () => LikeButtonDemo(), 25 | routeName: 'like button', 26 | description: 'show how to build like button', 27 | ); 28 | case 'fluttercandies://mainpage': 29 | return FFRouteSettings( 30 | name: name, 31 | arguments: arguments, 32 | builder: () => MainPage(), 33 | routeName: 'MainPage', 34 | ); 35 | default: 36 | return FFRouteSettings( 37 | name: FFRoute.notFoundName, 38 | routeName: FFRoute.notFoundRouteName, 39 | builder: notFoundPageBuilder ?? () => Container(), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /example/lib/example_routes.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY MANUALLY 2 | // ************************************************************************** 3 | // Auto generated by https://github.com/fluttercandies/ff_annotation_route 4 | // ************************************************************************** 5 | // ignore_for_file: prefer_const_literals_to_create_immutables,unused_local_variable,unused_import 6 | const List routeNames = [ 7 | 'fluttercandies://LikeButtonDemo', 8 | 'fluttercandies://mainpage', 9 | ]; 10 | 11 | class Routes { 12 | const Routes._(); 13 | 14 | /// 'show how to build like button' 15 | /// 16 | /// [name] : 'fluttercandies://LikeButtonDemo' 17 | /// 18 | /// [routeName] : 'like button' 19 | /// 20 | /// [description] : 'show how to build like button' 21 | static const String fluttercandiesLikeButtonDemo = 22 | 'fluttercandies://LikeButtonDemo'; 23 | 24 | /// 'MainPage' 25 | /// 26 | /// [name] : 'fluttercandies://mainpage' 27 | /// 28 | /// [routeName] : 'MainPage' 29 | /// 30 | /// [constructors] : 31 | /// 32 | /// MainPage : [] 33 | static const String fluttercandiesMainpage = 'fluttercandies://mainpage'; 34 | } 35 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'example_route.dart'; 4 | import 'example_routes.dart'; 5 | 6 | void main() => runApp(MyApp()); 7 | 8 | class MyApp extends StatelessWidget { 9 | // This widget is the root of your application. 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | debugShowCheckedModeBanner: false, 14 | theme: ThemeData( 15 | primarySwatch: Colors.blue, 16 | ), 17 | builder: (BuildContext c, Widget? w) { 18 | final MediaQueryData data = MediaQuery.of(c); 19 | return MediaQuery( 20 | data: data.copyWith(textScaleFactor: 1.0), 21 | child: w!, 22 | ); 23 | }, 24 | initialRoute: Routes.fluttercandiesMainpage, 25 | onGenerateRoute: (RouteSettings settings) { 26 | return onGenerateRoute( 27 | settings: settings, 28 | getRouteSettings: getRouteSettings, 29 | ); 30 | }, 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/lib/pages/like_button_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:like_button/like_button.dart'; 4 | 5 | /// 6 | /// create by zhoumaotuo on 2019/5/27 7 | /// 8 | 9 | const double buttonSize = 40.0; 10 | 11 | @FFRoute( 12 | name: 'fluttercandies://LikeButtonDemo', 13 | routeName: 'like button', 14 | description: 'show how to build like button', 15 | ) 16 | class LikeButtonDemo extends StatefulWidget { 17 | @override 18 | _LikeButtonDemoState createState() => _LikeButtonDemoState(); 19 | } 20 | 21 | class _LikeButtonDemoState extends State { 22 | final int likeCount = 999; 23 | final GlobalKey _globalKey = GlobalKey(); 24 | @override 25 | Widget build(BuildContext context) { 26 | return Scaffold( 27 | appBar: AppBar( 28 | title: const Text('Like Button Demo'), 29 | ), 30 | body: GridView( 31 | gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( 32 | maxCrossAxisExtent: 300), 33 | children: [ 34 | LikeButton( 35 | size: buttonSize, 36 | likeCount: likeCount, 37 | key: _globalKey, 38 | isLiked: true, 39 | postFrameCallback: (LikeButtonState state) { 40 | state.controller?.forward(); 41 | }, 42 | countBuilder: (int? count, bool isLiked, String text) { 43 | final ColorSwatch color = 44 | isLiked ? Colors.pinkAccent : Colors.grey; 45 | Widget result; 46 | if (count == 0) { 47 | result = Text( 48 | 'love', 49 | style: TextStyle(color: color), 50 | ); 51 | } else 52 | result = Text( 53 | count! >= 1000 54 | ? (count / 1000.0).toStringAsFixed(1) + 'k' 55 | : text, 56 | style: TextStyle(color: color), 57 | ); 58 | return result; 59 | }, 60 | likeCountAnimationType: likeCount < 1000 61 | ? LikeCountAnimationType.part 62 | : LikeCountAnimationType.none, 63 | likeCountPadding: const EdgeInsets.only(left: 15.0), 64 | onTap: onLikeButtonTapped, 65 | ), 66 | LikeButton( 67 | size: buttonSize, 68 | circleColor: const CircleColor( 69 | start: Color(0xff00ddff), end: Color(0xff0099cc)), 70 | bubblesColor: const BubblesColor( 71 | dotPrimaryColor: Color(0xff33b5e5), 72 | dotSecondaryColor: Color(0xff0099cc), 73 | ), 74 | likeBuilder: (bool isLiked) { 75 | return Icon( 76 | Icons.home, 77 | color: isLiked ? Colors.deepPurpleAccent : Colors.grey, 78 | size: buttonSize, 79 | ); 80 | }, 81 | likeCount: 665, 82 | countBuilder: (int? count, bool isLiked, String text) { 83 | final ColorSwatch color = 84 | isLiked ? Colors.deepPurpleAccent : Colors.grey; 85 | Widget result; 86 | if (count == 0) { 87 | result = Text( 88 | 'love', 89 | style: TextStyle(color: color), 90 | ); 91 | } else 92 | result = Text( 93 | text, 94 | style: TextStyle(color: color), 95 | ); 96 | return result; 97 | }, 98 | likeCountPadding: const EdgeInsets.only(left: 15.0), 99 | ), 100 | LikeButton( 101 | size: buttonSize, 102 | circleColor: const CircleColor( 103 | start: Color(0xff669900), end: Color(0xff669900)), 104 | bubblesColor: const BubblesColor( 105 | dotPrimaryColor: Color(0xff669900), 106 | dotSecondaryColor: Color(0xff99cc00), 107 | ), 108 | likeBuilder: (bool isLiked) { 109 | return Icon( 110 | Icons.adb, 111 | color: isLiked ? Colors.green : Colors.grey, 112 | size: buttonSize, 113 | ); 114 | }, 115 | likeCount: 665, 116 | likeCountAnimationType: LikeCountAnimationType.all, 117 | countBuilder: (int? count, bool isLiked, String text) { 118 | final MaterialColor color = isLiked ? Colors.green : Colors.grey; 119 | Widget result; 120 | if (count == 0) { 121 | result = Text( 122 | 'love', 123 | style: TextStyle(color: color), 124 | ); 125 | } else 126 | result = Text( 127 | text, 128 | style: TextStyle(color: color), 129 | ); 130 | return result; 131 | }, 132 | likeCountPadding: const EdgeInsets.only(left: 15.0), 133 | ), 134 | LikeButton( 135 | size: buttonSize, 136 | isLiked: null, 137 | circleColor: CircleColor( 138 | start: Colors.redAccent[100]!, 139 | end: Colors.redAccent[400]!, 140 | ), 141 | bubblesColor: BubblesColor( 142 | dotPrimaryColor: Colors.red[300]!, 143 | dotSecondaryColor: Colors.red[200]!, 144 | ), 145 | likeBuilder: (bool isLiked) { 146 | return const Icon( 147 | Icons.assistant_photo, 148 | color: Colors.red, 149 | size: buttonSize, 150 | ); 151 | }, 152 | likeCount: 888, 153 | countBuilder: (int? count, bool isLiked, String text) { 154 | return Text( 155 | count == 0 ? 'love' : text, 156 | style: const TextStyle(color: Colors.red), 157 | ); 158 | }, 159 | likeCountPadding: const EdgeInsets.only(left: 15.0), 160 | ), 161 | LikeButton( 162 | size: buttonSize, 163 | circleColor: CircleColor( 164 | start: Colors.pinkAccent[200]!, end: Colors.pinkAccent[400]!), 165 | bubblesColor: BubblesColor( 166 | dotPrimaryColor: Colors.lightBlue[300]!, 167 | dotSecondaryColor: Colors.lightBlue[200]!, 168 | ), 169 | likeBuilder: (bool isLiked) { 170 | return Icon( 171 | Icons.insert_emoticon, 172 | color: isLiked ? Colors.lightBlueAccent : Colors.grey, 173 | size: buttonSize, 174 | ); 175 | }, 176 | ), 177 | LikeButton( 178 | size: buttonSize, 179 | isLiked: null, 180 | circleColor: CircleColor( 181 | start: Colors.grey[200]!, 182 | end: Colors.grey[400]!, 183 | ), 184 | bubblesColor: BubblesColor( 185 | dotPrimaryColor: Colors.grey[600]!, 186 | dotSecondaryColor: Colors.grey[200]!, 187 | ), 188 | likeBuilder: (bool isLiked) { 189 | return Icon( 190 | Icons.cloud, 191 | color: isLiked ? Colors.grey[900] : Colors.grey, 192 | size: buttonSize, 193 | ); 194 | }, 195 | likeCount: 888, 196 | countPostion: CountPostion.left, 197 | countBuilder: (int? count, bool isLiked, String text) { 198 | return Text( 199 | count == 0 ? 'love' : text, 200 | style: const TextStyle(color: Colors.grey), 201 | ); 202 | }, 203 | likeCountPadding: const EdgeInsets.only(right: 15.0), 204 | ), 205 | LikeButton( 206 | size: buttonSize, 207 | isLiked: null, 208 | circleColor: CircleColor( 209 | start: Colors.indigoAccent[200]!, 210 | end: Colors.indigoAccent[400]!, 211 | ), 212 | bubblesColor: BubblesColor( 213 | dotPrimaryColor: Colors.indigoAccent[700]!, 214 | dotSecondaryColor: Colors.indigoAccent[200]!, 215 | ), 216 | likeBuilder: (bool isLiked) { 217 | return Icon( 218 | Icons.access_alarm, 219 | color: isLiked ? Colors.indigoAccent[700] : Colors.grey, 220 | size: buttonSize, 221 | ); 222 | }, 223 | likeCount: 888, 224 | countPostion: CountPostion.bottom, 225 | countBuilder: (int? count, bool isLiked, String text) { 226 | return Text( 227 | text, 228 | style: const TextStyle(color: Colors.grey), 229 | ); 230 | }, 231 | likeCountPadding: const EdgeInsets.only(top: 15.0), 232 | countDecoration: (Widget count, int? likeCount) { 233 | return Row( 234 | mainAxisAlignment: MainAxisAlignment.center, 235 | crossAxisAlignment: CrossAxisAlignment.center, 236 | children: [ 237 | count, 238 | const SizedBox( 239 | width: 10.0, 240 | ), 241 | const Text( 242 | 'loves', 243 | style: TextStyle(color: Colors.indigoAccent), 244 | ) 245 | ], 246 | ); 247 | }, 248 | ), 249 | LikeButton( 250 | size: buttonSize, 251 | isLiked: null, 252 | circleColor: CircleColor( 253 | start: Colors.orange[200]!, 254 | end: Colors.orange[400]!, 255 | ), 256 | bubblesColor: BubblesColor( 257 | dotPrimaryColor: Colors.orange[600]!, 258 | dotSecondaryColor: Colors.orange[200]!, 259 | ), 260 | likeBuilder: (bool isLiked) { 261 | return Icon( 262 | Icons.camera_alt, 263 | color: isLiked ? Colors.orange[900] : Colors.grey, 264 | size: buttonSize, 265 | ); 266 | }, 267 | likeCount: 888, 268 | countPostion: CountPostion.top, 269 | countBuilder: (int? count, bool isLiked, String text) { 270 | return Text( 271 | text, 272 | style: const TextStyle(color: Colors.grey), 273 | ); 274 | }, 275 | likeCountPadding: const EdgeInsets.only(bottom: 15.0), 276 | countDecoration: (Widget count, int? likeCount) { 277 | return Row( 278 | mainAxisAlignment: MainAxisAlignment.center, 279 | crossAxisAlignment: CrossAxisAlignment.center, 280 | children: [ 281 | count, 282 | const SizedBox( 283 | width: 10.0, 284 | ), 285 | const Text( 286 | 'loves', 287 | style: TextStyle(color: Colors.orange), 288 | ) 289 | ], 290 | ); 291 | }, 292 | ), 293 | ], 294 | ), 295 | floatingActionButton: FloatingActionButton( 296 | child: const Icon(Icons.favorite), 297 | onPressed: () { 298 | _globalKey.currentState!.onTap(); 299 | }, 300 | ), 301 | ); 302 | } 303 | 304 | Future onLikeButtonTapped(bool isLiked) async { 305 | /// send your request here 306 | // final bool success= await sendRequest(); 307 | 308 | /// if failed, you can do nothing 309 | // return success? !isLiked:isLiked; 310 | 311 | return !isLiked; 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /example/lib/pages/main_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:example/example_routes.dart'; 2 | import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; 3 | import 'package:flutter/material.dart'; 4 | import '../example_route.dart'; 5 | import '../example_routes.dart' as example_routes; 6 | 7 | @FFRoute( 8 | name: 'fluttercandies://mainpage', 9 | routeName: 'MainPage', 10 | ) 11 | class MainPage extends StatelessWidget { 12 | MainPage() { 13 | final List routeNames = []; 14 | routeNames.addAll(example_routes.routeNames); 15 | routeNames.remove(Routes.fluttercandiesMainpage); 16 | routes.addAll(routeNames 17 | .map((String name) => getRouteSettings(name: name))); 18 | } 19 | final List routes = []; 20 | @override 21 | Widget build(BuildContext context) { 22 | return Scaffold( 23 | appBar: AppBar( 24 | // Here we take the value from the MyHomePage object that was created by 25 | // the App.build method, and use it to set our appbar title. 26 | title: const Text('like button demo'), 27 | ), 28 | body: ListView.builder( 29 | itemBuilder: (BuildContext c, int index) { 30 | final FFRouteSettings page = routes[index]; 31 | return Container( 32 | margin: const EdgeInsets.all(20.0), 33 | child: GestureDetector( 34 | behavior: HitTestBehavior.translucent, 35 | child: Column( 36 | crossAxisAlignment: CrossAxisAlignment.start, 37 | children: [ 38 | Text( 39 | (index + 1).toString() + '.' + page.routeName!, 40 | //style: TextStyle(inherit: false), 41 | ), 42 | Text( 43 | page.description!, 44 | style: const TextStyle(color: Colors.grey), 45 | ) 46 | ], 47 | ), 48 | onTap: () { 49 | Navigator.pushNamed(context, routes[index].name!); 50 | }, 51 | )); 52 | }, 53 | itemCount: routes.length, 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | 9 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 10 | } 11 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; 13 | buildPhases = ( 14 | 33CC111E2044C6BF0003C045 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = "Flutter Assemble"; 19 | productName = FLX; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 25 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 26 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 27 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 28 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 33CC111A2044C6BA0003C045; 37 | remoteInfo = FLX; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | 33CC110E2044A8840003C045 /* Bundle Framework */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | ); 49 | name = "Bundle Framework"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXCopyFilesBuildPhase section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 56 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; 57 | 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 59 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 60 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 61 | 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; 62 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; 63 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 64 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 65 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; 66 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 67 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 68 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 70 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 33CC10EA2044A3C60003C045 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 33BA886A226E78AF003329D5 /* Configs */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */, 88 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 89 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 90 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, 91 | ); 92 | path = Configs; 93 | sourceTree = ""; 94 | }; 95 | 33CC10E42044A3C60003C045 = { 96 | isa = PBXGroup; 97 | children = ( 98 | 33FAB671232836740065AC1E /* Runner */, 99 | 33CEB47122A05771004F2AC0 /* Flutter */, 100 | 33CC10EE2044A3C60003C045 /* Products */, 101 | D73912EC22F37F3D000D13A0 /* Frameworks */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 33CC10EE2044A3C60003C045 /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 33CC10ED2044A3C60003C045 /* example.app */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 33CC11242044D66E0003C045 /* Resources */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 33CC10F22044A3C60003C045 /* Assets.xcassets */, 117 | 33CC10F42044A3C60003C045 /* MainMenu.xib */, 118 | 33CC10F72044A3C60003C045 /* Info.plist */, 119 | ); 120 | name = Resources; 121 | path = ..; 122 | sourceTree = ""; 123 | }; 124 | 33CEB47122A05771004F2AC0 /* Flutter */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, 128 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 129 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 130 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, 131 | ); 132 | path = Flutter; 133 | sourceTree = ""; 134 | }; 135 | 33FAB671232836740065AC1E /* Runner */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */, 139 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, 140 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */, 141 | 33E51914231749380026EE4D /* Release.entitlements */, 142 | 33CC11242044D66E0003C045 /* Resources */, 143 | 33BA886A226E78AF003329D5 /* Configs */, 144 | ); 145 | path = Runner; 146 | sourceTree = ""; 147 | }; 148 | D73912EC22F37F3D000D13A0 /* Frameworks */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | ); 152 | name = Frameworks; 153 | sourceTree = ""; 154 | }; 155 | /* End PBXGroup section */ 156 | 157 | /* Begin PBXNativeTarget section */ 158 | 33CC10EC2044A3C60003C045 /* Runner */ = { 159 | isa = PBXNativeTarget; 160 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; 161 | buildPhases = ( 162 | 33CC10E92044A3C60003C045 /* Sources */, 163 | 33CC10EA2044A3C60003C045 /* Frameworks */, 164 | 33CC10EB2044A3C60003C045 /* Resources */, 165 | 33CC110E2044A8840003C045 /* Bundle Framework */, 166 | 3399D490228B24CF009A79C7 /* ShellScript */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | 33CC11202044C79F0003C045 /* PBXTargetDependency */, 172 | ); 173 | name = Runner; 174 | productName = Runner; 175 | productReference = 33CC10ED2044A3C60003C045 /* example.app */; 176 | productType = "com.apple.product-type.application"; 177 | }; 178 | /* End PBXNativeTarget section */ 179 | 180 | /* Begin PBXProject section */ 181 | 33CC10E52044A3C60003C045 /* Project object */ = { 182 | isa = PBXProject; 183 | attributes = { 184 | LastSwiftUpdateCheck = 0920; 185 | LastUpgradeCheck = 0930; 186 | ORGANIZATIONNAME = "The Flutter Authors"; 187 | TargetAttributes = { 188 | 33CC10EC2044A3C60003C045 = { 189 | CreatedOnToolsVersion = 9.2; 190 | LastSwiftMigration = 1100; 191 | ProvisioningStyle = Automatic; 192 | SystemCapabilities = { 193 | com.apple.Sandbox = { 194 | enabled = 1; 195 | }; 196 | }; 197 | }; 198 | 33CC111A2044C6BA0003C045 = { 199 | CreatedOnToolsVersion = 9.2; 200 | ProvisioningStyle = Manual; 201 | }; 202 | }; 203 | }; 204 | buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; 205 | compatibilityVersion = "Xcode 8.0"; 206 | developmentRegion = en; 207 | hasScannedForEncodings = 0; 208 | knownRegions = ( 209 | en, 210 | Base, 211 | ); 212 | mainGroup = 33CC10E42044A3C60003C045; 213 | productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; 214 | projectDirPath = ""; 215 | projectRoot = ""; 216 | targets = ( 217 | 33CC10EC2044A3C60003C045 /* Runner */, 218 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */, 219 | ); 220 | }; 221 | /* End PBXProject section */ 222 | 223 | /* Begin PBXResourcesBuildPhase section */ 224 | 33CC10EB2044A3C60003C045 /* Resources */ = { 225 | isa = PBXResourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 229 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXResourcesBuildPhase section */ 234 | 235 | /* Begin PBXShellScriptBuildPhase section */ 236 | 3399D490228B24CF009A79C7 /* ShellScript */ = { 237 | isa = PBXShellScriptBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | ); 241 | inputFileListPaths = ( 242 | ); 243 | inputPaths = ( 244 | ); 245 | outputFileListPaths = ( 246 | ); 247 | outputPaths = ( 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; 252 | }; 253 | 33CC111E2044C6BF0003C045 /* ShellScript */ = { 254 | isa = PBXShellScriptBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputFileListPaths = ( 259 | Flutter/ephemeral/FlutterInputs.xcfilelist, 260 | ); 261 | inputPaths = ( 262 | Flutter/ephemeral/tripwire, 263 | ); 264 | outputFileListPaths = ( 265 | Flutter/ephemeral/FlutterOutputs.xcfilelist, 266 | ); 267 | outputPaths = ( 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | shellPath = /bin/sh; 271 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; 272 | }; 273 | /* End PBXShellScriptBuildPhase section */ 274 | 275 | /* Begin PBXSourcesBuildPhase section */ 276 | 33CC10E92044A3C60003C045 /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 281 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, 282 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin PBXTargetDependency section */ 289 | 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { 290 | isa = PBXTargetDependency; 291 | target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; 292 | targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; 293 | }; 294 | /* End PBXTargetDependency section */ 295 | 296 | /* Begin PBXVariantGroup section */ 297 | 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { 298 | isa = PBXVariantGroup; 299 | children = ( 300 | 33CC10F52044A3C60003C045 /* Base */, 301 | ); 302 | name = MainMenu.xib; 303 | path = Runner; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXVariantGroup section */ 307 | 308 | /* Begin XCBuildConfiguration section */ 309 | 338D0CE9231458BD00FA5F75 /* Profile */ = { 310 | isa = XCBuildConfiguration; 311 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 316 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 317 | CLANG_CXX_LIBRARY = "libc++"; 318 | CLANG_ENABLE_MODULES = YES; 319 | CLANG_ENABLE_OBJC_ARC = YES; 320 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 326 | CLANG_WARN_EMPTY_BODY = YES; 327 | CLANG_WARN_ENUM_CONVERSION = YES; 328 | CLANG_WARN_INFINITE_RECURSION = YES; 329 | CLANG_WARN_INT_CONVERSION = YES; 330 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 335 | CODE_SIGN_IDENTITY = "-"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | GCC_C_LANGUAGE_STANDARD = gnu11; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | MACOSX_DEPLOYMENT_TARGET = 10.11; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | SDKROOT = macosx; 350 | SWIFT_COMPILATION_MODE = wholemodule; 351 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 352 | }; 353 | name = Profile; 354 | }; 355 | 338D0CEA231458BD00FA5F75 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 362 | CODE_SIGN_STYLE = Automatic; 363 | COMBINE_HIDPI_IMAGES = YES; 364 | FRAMEWORK_SEARCH_PATHS = ( 365 | "$(inherited)", 366 | "$(PROJECT_DIR)/Flutter/ephemeral", 367 | ); 368 | INFOPLIST_FILE = Runner/Info.plist; 369 | LD_RUNPATH_SEARCH_PATHS = ( 370 | "$(inherited)", 371 | "@executable_path/../Frameworks", 372 | ); 373 | PROVISIONING_PROFILE_SPECIFIER = ""; 374 | SWIFT_VERSION = 5.0; 375 | }; 376 | name = Profile; 377 | }; 378 | 338D0CEB231458BD00FA5F75 /* Profile */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | CODE_SIGN_STYLE = Manual; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | }; 384 | name = Profile; 385 | }; 386 | 33CC10F92044A3C60003C045 /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 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_CONSTANT_CONVERSION = YES; 400 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 401 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 402 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 403 | CLANG_WARN_EMPTY_BODY = YES; 404 | CLANG_WARN_ENUM_CONVERSION = YES; 405 | CLANG_WARN_INFINITE_RECURSION = YES; 406 | CLANG_WARN_INT_CONVERSION = YES; 407 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 409 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 410 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 411 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 412 | CODE_SIGN_IDENTITY = "-"; 413 | COPY_PHASE_STRIP = NO; 414 | DEBUG_INFORMATION_FORMAT = dwarf; 415 | ENABLE_STRICT_OBJC_MSGSEND = YES; 416 | ENABLE_TESTABILITY = YES; 417 | GCC_C_LANGUAGE_STANDARD = gnu11; 418 | GCC_DYNAMIC_NO_PIC = NO; 419 | GCC_NO_COMMON_BLOCKS = YES; 420 | GCC_OPTIMIZATION_LEVEL = 0; 421 | GCC_PREPROCESSOR_DEFINITIONS = ( 422 | "DEBUG=1", 423 | "$(inherited)", 424 | ); 425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 426 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 427 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 428 | GCC_WARN_UNUSED_FUNCTION = YES; 429 | GCC_WARN_UNUSED_VARIABLE = YES; 430 | MACOSX_DEPLOYMENT_TARGET = 10.11; 431 | MTL_ENABLE_DEBUG_INFO = YES; 432 | ONLY_ACTIVE_ARCH = YES; 433 | SDKROOT = macosx; 434 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 435 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 436 | }; 437 | name = Debug; 438 | }; 439 | 33CC10FA2044A3C60003C045 /* Release */ = { 440 | isa = XCBuildConfiguration; 441 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 442 | buildSettings = { 443 | ALWAYS_SEARCH_USER_PATHS = NO; 444 | CLANG_ANALYZER_NONNULL = YES; 445 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 446 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 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_CONSTANT_CONVERSION = YES; 453 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 454 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 455 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 456 | CLANG_WARN_EMPTY_BODY = YES; 457 | CLANG_WARN_ENUM_CONVERSION = YES; 458 | CLANG_WARN_INFINITE_RECURSION = YES; 459 | CLANG_WARN_INT_CONVERSION = YES; 460 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 461 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 462 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 463 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 464 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 465 | CODE_SIGN_IDENTITY = "-"; 466 | COPY_PHASE_STRIP = NO; 467 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 468 | ENABLE_NS_ASSERTIONS = NO; 469 | ENABLE_STRICT_OBJC_MSGSEND = YES; 470 | GCC_C_LANGUAGE_STANDARD = gnu11; 471 | GCC_NO_COMMON_BLOCKS = YES; 472 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 473 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 474 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 475 | GCC_WARN_UNUSED_FUNCTION = YES; 476 | GCC_WARN_UNUSED_VARIABLE = YES; 477 | MACOSX_DEPLOYMENT_TARGET = 10.11; 478 | MTL_ENABLE_DEBUG_INFO = NO; 479 | SDKROOT = macosx; 480 | SWIFT_COMPILATION_MODE = wholemodule; 481 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 482 | }; 483 | name = Release; 484 | }; 485 | 33CC10FC2044A3C60003C045 /* Debug */ = { 486 | isa = XCBuildConfiguration; 487 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 488 | buildSettings = { 489 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 490 | CLANG_ENABLE_MODULES = YES; 491 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 492 | CODE_SIGN_STYLE = Automatic; 493 | COMBINE_HIDPI_IMAGES = YES; 494 | FRAMEWORK_SEARCH_PATHS = ( 495 | "$(inherited)", 496 | "$(PROJECT_DIR)/Flutter/ephemeral", 497 | ); 498 | INFOPLIST_FILE = Runner/Info.plist; 499 | LD_RUNPATH_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "@executable_path/../Frameworks", 502 | ); 503 | PROVISIONING_PROFILE_SPECIFIER = ""; 504 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 505 | SWIFT_VERSION = 5.0; 506 | }; 507 | name = Debug; 508 | }; 509 | 33CC10FD2044A3C60003C045 /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 512 | buildSettings = { 513 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 514 | CLANG_ENABLE_MODULES = YES; 515 | CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; 516 | CODE_SIGN_STYLE = Automatic; 517 | COMBINE_HIDPI_IMAGES = YES; 518 | FRAMEWORK_SEARCH_PATHS = ( 519 | "$(inherited)", 520 | "$(PROJECT_DIR)/Flutter/ephemeral", 521 | ); 522 | INFOPLIST_FILE = Runner/Info.plist; 523 | LD_RUNPATH_SEARCH_PATHS = ( 524 | "$(inherited)", 525 | "@executable_path/../Frameworks", 526 | ); 527 | PROVISIONING_PROFILE_SPECIFIER = ""; 528 | SWIFT_VERSION = 5.0; 529 | }; 530 | name = Release; 531 | }; 532 | 33CC111C2044C6BA0003C045 /* Debug */ = { 533 | isa = XCBuildConfiguration; 534 | buildSettings = { 535 | CODE_SIGN_STYLE = Manual; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | }; 538 | name = Debug; 539 | }; 540 | 33CC111D2044C6BA0003C045 /* Release */ = { 541 | isa = XCBuildConfiguration; 542 | buildSettings = { 543 | CODE_SIGN_STYLE = Automatic; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | }; 546 | name = Release; 547 | }; 548 | /* End XCBuildConfiguration section */ 549 | 550 | /* Begin XCConfigurationList section */ 551 | 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { 552 | isa = XCConfigurationList; 553 | buildConfigurations = ( 554 | 33CC10F92044A3C60003C045 /* Debug */, 555 | 33CC10FA2044A3C60003C045 /* Release */, 556 | 338D0CE9231458BD00FA5F75 /* Profile */, 557 | ); 558 | defaultConfigurationIsVisible = 0; 559 | defaultConfigurationName = Release; 560 | }; 561 | 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | 33CC10FC2044A3C60003C045 /* Debug */, 565 | 33CC10FD2044A3C60003C045 /* Release */, 566 | 338D0CEA231458BD00FA5F75 /* Profile */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | 33CC111C2044C6BA0003C045 /* Debug */, 575 | 33CC111D2044C6BA0003C045 /* Release */, 576 | 338D0CEB231458BD00FA5F75 /* Profile */, 577 | ); 578 | defaultConfigurationIsVisible = 0; 579 | defaultConfigurationName = Release; 580 | }; 581 | /* End XCConfigurationList section */ 582 | }; 583 | rootObject = 33CC10E52044A3C60003C045 /* Project object */; 584 | } 585 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/macos/Runner/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 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 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.zmtzawqlp.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2020 com.zmtzawqlp. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A new Flutter application. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | publish_to: none 16 | 17 | environment: 18 | sdk: '>=2.12.0 <3.0.0' 19 | flutter: '>=2.0.0' 20 | dependencies: 21 | cupertino_icons: ^0.1.2 22 | ff_annotation_route_library: ^3.0.0 23 | flutter: 24 | sdk: flutter 25 | 26 | like_button: 27 | path: ../ 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | 34 | # For information on the generic Dart part of this file, see the 35 | # following page: https://www.dartlang.org/tools/pub/pubspec 36 | 37 | # The following section is specific to Flutter. 38 | flutter: 39 | # assets: 40 | # - assets/ 41 | # The following line ensures that the Material Icons font is 42 | # included with your application, so that you can use the icons in 43 | # the material Icons class. 44 | uses-material-design: true 45 | 46 | # To add assets to your application, add an assets section, like this: 47 | # assets: 48 | # - images/a_dot_burr.jpeg 49 | # - images/a_dot_ham.jpeg 50 | 51 | # An image asset can refer to one or more resolution-specific "variants", see 52 | # https://flutter.dev/assets-and-images/#resolution-aware. 53 | 54 | # For details regarding adding assets from package dependencies, see 55 | # https://flutter.dev/assets-and-images/#from-packages 56 | 57 | # To add custom fonts to your application, add a fonts section here, 58 | # in this "flutter" section. Each entry in this list should have a 59 | # "family" key with the font family name, and a "fonts" key with a 60 | # list giving the asset and other descriptors for the font. For 61 | # example: 62 | # fonts: 63 | # - family: Schyler 64 | # fonts: 65 | # - asset: fonts/Schyler-Regular.ttf 66 | # - asset: fonts/Schyler-Italic.ttf 67 | # style: italic 68 | # - family: Trajan Pro 69 | # fonts: 70 | # - asset: fonts/TrajanPro.ttf 71 | # - asset: fonts/TrajanPro_Bold.ttf 72 | # weight: 700 73 | # 74 | # For details regarding fonts from package dependencies, 75 | # see https://flutter.dev/custom-fonts/#from-packages 76 | -------------------------------------------------------------------------------- /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 | import 'package:example/main.dart'; 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | void main() { 12 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 13 | // Build our app and trigger a frame. 14 | await tester.pumpWidget(MyApp()); 15 | 16 | // Verify that our counter starts at 0. 17 | expect(find.text('0'), findsOneWidget); 18 | expect(find.text('1'), findsNothing); 19 | 20 | // Tap the '+' icon and trigger a frame. 21 | await tester.tap(find.byIcon(Icons.add)); 22 | await tester.pump(); 23 | 24 | // Verify that our counter has incremented. 25 | expect(find.text('0'), findsNothing); 26 | expect(find.text('1'), findsOneWidget); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/like_button/856f91613246d2601782b118841b4f2eea7fb3f6/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | example 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /lib/like_button.dart: -------------------------------------------------------------------------------- 1 | library like_button; 2 | 3 | export 'src/like_button.dart'; 4 | export 'src/utils/like_button_model.dart'; 5 | export 'src/utils/like_button_typedef.dart'; 6 | -------------------------------------------------------------------------------- /lib/src/like_button.dart: -------------------------------------------------------------------------------- 1 | /// 2 | /// create by zmtzawqlp on 2019/5/27 3 | /// 4 | import 'package:flutter/material.dart'; 5 | import 'package:like_button/src/painter/bubbles_painter.dart'; 6 | import 'package:like_button/src/painter/circle_painter.dart'; 7 | import 'package:like_button/src/utils/like_button_model.dart'; 8 | import 'package:like_button/src/utils/like_button_typedef.dart'; 9 | import 'package:like_button/src/utils/like_button_util.dart'; 10 | 11 | class LikeButton extends StatefulWidget { 12 | const LikeButton({ 13 | Key? key, 14 | this.size = 30.0, 15 | this.likeBuilder, 16 | this.countBuilder, 17 | double? bubblesSize, 18 | double? circleSize, 19 | this.likeCount, 20 | this.isLiked = false, 21 | this.mainAxisAlignment = MainAxisAlignment.center, 22 | this.crossAxisAlignment = CrossAxisAlignment.center, 23 | this.animationDuration = const Duration(milliseconds: 1000), 24 | this.likeCountAnimationType = LikeCountAnimationType.part, 25 | this.likeCountAnimationDuration = const Duration(milliseconds: 500), 26 | this.likeCountPadding = const EdgeInsets.only(left: 3.0), 27 | this.bubblesColor = const BubblesColor( 28 | dotPrimaryColor: Color(0xFFFFC107), 29 | dotSecondaryColor: Color(0xFFFF9800), 30 | dotThirdColor: Color(0xFFFF5722), 31 | dotLastColor: Color(0xFFF44336), 32 | ), 33 | this.circleColor = 34 | const CircleColor(start: Color(0xFFFF5722), end: Color(0xFFFFC107)), 35 | this.onTap, 36 | this.countPostion = CountPostion.right, 37 | this.padding, 38 | this.countDecoration, 39 | this.postFrameCallback, 40 | }) : bubblesSize = bubblesSize ?? size * 2.0, 41 | circleSize = circleSize ?? size * 0.8, 42 | super(key: key); 43 | 44 | /// size of like widget 45 | final double size; 46 | 47 | /// animation duration to change isLiked state 48 | final Duration animationDuration; 49 | 50 | /// total size of bubbles 51 | final double bubblesSize; 52 | 53 | /// colors of bubbles 54 | final BubblesColor bubblesColor; 55 | 56 | /// size of circle 57 | final double circleSize; 58 | 59 | /// colors of circle 60 | final CircleColor circleColor; 61 | 62 | /// tap call back of like button 63 | final LikeButtonTapCallback? onTap; 64 | 65 | /// whether it is liked 66 | /// it's initial value 67 | /// you can get current value from onTap/countBuilder 68 | final bool? isLiked; 69 | 70 | /// like count 71 | /// if null, will not show 72 | /// it's initial value 73 | /// you can get current value from countBuilder 74 | final int? likeCount; 75 | 76 | /// mainAxisAlignment for like button 77 | final MainAxisAlignment mainAxisAlignment; 78 | 79 | /// crossAxisAlignment for like button 80 | final CrossAxisAlignment crossAxisAlignment; 81 | 82 | /// builder to create like widget 83 | final LikeWidgetBuilder? likeBuilder; 84 | 85 | /// builder to create like count widget 86 | final LikeCountWidgetBuilder? countBuilder; 87 | 88 | /// animation duration to change like count 89 | final Duration likeCountAnimationDuration; 90 | 91 | /// animation type to change like count(none,part,all) 92 | final LikeCountAnimationType likeCountAnimationType; 93 | 94 | /// padding for like count widget 95 | final EdgeInsetsGeometry? likeCountPadding; 96 | 97 | /// like count widget postion 98 | /// left of like widget 99 | /// right of like widget 100 | /// top of like widget 101 | /// bottom of like widget 102 | final CountPostion countPostion; 103 | 104 | /// padding of like button 105 | final EdgeInsetsGeometry? padding; 106 | 107 | /// return count widget with decoration 108 | final CountDecoration? countDecoration; 109 | 110 | /// call back of first frame with LikeButtonState 111 | final Function(LikeButtonState state)? postFrameCallback; 112 | 113 | @override 114 | State createState() => LikeButtonState(); 115 | } 116 | 117 | class LikeButtonState extends State with TickerProviderStateMixin { 118 | AnimationController? _controller; 119 | late Animation _outerCircleAnimation; 120 | late Animation _innerCircleAnimation; 121 | late Animation _scaleAnimation; 122 | late Animation _bubblesAnimation; 123 | late Animation _slidePreValueAnimation; 124 | late Animation _slideCurrentValueAnimation; 125 | AnimationController? _likeCountController; 126 | late Animation _opacityAnimation; 127 | 128 | AnimationController? get controller => _controller; 129 | AnimationController? get likeCountController => _likeCountController; 130 | 131 | bool? _isLiked = false; 132 | int? _likeCount; 133 | int? _preLikeCount; 134 | 135 | bool? get isLiked => _isLiked; 136 | int? get likeCount => _likeCount; 137 | int? get preLikeCount => _preLikeCount; 138 | @override 139 | void initState() { 140 | super.initState(); 141 | 142 | _isLiked = widget.isLiked; 143 | 144 | _likeCount = widget.likeCount; 145 | _preLikeCount = _likeCount; 146 | 147 | _controller = 148 | AnimationController(duration: widget.animationDuration, vsync: this); 149 | _likeCountController = AnimationController( 150 | duration: widget.likeCountAnimationDuration, vsync: this); 151 | 152 | _initAnimations(); 153 | 154 | if (widget.postFrameCallback != null) { 155 | // ignore: unnecessary_cast 156 | (WidgetsBinding.instance as WidgetsBinding) 157 | .addPostFrameCallback((Duration timeStamp) { 158 | widget.postFrameCallback!.call(this); 159 | }); 160 | } 161 | } 162 | 163 | @override 164 | void didUpdateWidget(LikeButton oldWidget) { 165 | // Check if isLiked state has changed from props 166 | if (widget.isLiked != oldWidget.isLiked && widget.isLiked != _isLiked) { 167 | // Play animation when isLiked becomes true 168 | if (widget.isLiked == true) { 169 | _playLikeAnimation(); 170 | } 171 | 172 | // Update internal state 173 | _updateLikeState(widget.isLiked); 174 | } 175 | 176 | // Update like count if changed 177 | if (widget.likeCount != _likeCount) { 178 | _preLikeCount = _likeCount; 179 | _likeCount = widget.likeCount; 180 | 181 | // Play like count animation if needed 182 | if (widget.likeCountAnimationType != LikeCountAnimationType.none && 183 | _preLikeCount != _likeCount) { 184 | _likeCountController?.reset(); 185 | _likeCountController?.forward(); 186 | } 187 | } 188 | 189 | // Check if animation duration config changed 190 | if (_controller?.duration != widget.animationDuration) { 191 | _controller?.dispose(); 192 | _controller = 193 | AnimationController(duration: widget.animationDuration, vsync: this); 194 | _initControlAnimation(); 195 | } 196 | 197 | if (_likeCountController?.duration != widget.likeCountAnimationDuration) { 198 | _likeCountController?.dispose(); 199 | _likeCountController = AnimationController( 200 | duration: widget.likeCountAnimationDuration, vsync: this); 201 | _initLikeCountControllerAnimation(); 202 | } 203 | 204 | super.didUpdateWidget(oldWidget); 205 | } 206 | 207 | // Play like animation 208 | void _playLikeAnimation() { 209 | if (!(_controller?.isAnimating ?? false)) { 210 | _controller?.reset(); 211 | _controller?.forward(); 212 | } 213 | } 214 | 215 | // Update like state without animation (used for prop updates) 216 | void _updateLikeState(bool? isLiked) { 217 | _isLiked = isLiked; 218 | } 219 | 220 | @override 221 | void dispose() { 222 | _controller!.dispose(); 223 | _likeCountController!.dispose(); 224 | super.dispose(); 225 | } 226 | 227 | @override 228 | Widget build(BuildContext context) { 229 | Widget likeCountWidget = _getLikeCountWidget(); 230 | if (widget.countDecoration != null) { 231 | likeCountWidget = widget.countDecoration!(likeCountWidget, _likeCount) ?? 232 | likeCountWidget; 233 | } 234 | if (widget.likeCountPadding != null) { 235 | likeCountWidget = Padding( 236 | padding: widget.likeCountPadding!, 237 | child: likeCountWidget, 238 | ); 239 | } 240 | 241 | List children = [ 242 | AnimatedBuilder( 243 | animation: _controller!, 244 | builder: (BuildContext c, Widget? w) { 245 | final Widget likeWidget = 246 | widget.likeBuilder?.call(_isLiked ?? true) ?? 247 | defaultWidgetBuilder(_isLiked ?? true, widget.size); 248 | return Stack( 249 | clipBehavior: Clip.none, 250 | children: [ 251 | Positioned( 252 | top: (widget.size - widget.bubblesSize) / 2.0, 253 | left: (widget.size - widget.bubblesSize) / 2.0, 254 | child: CustomPaint( 255 | size: Size(widget.bubblesSize, widget.bubblesSize), 256 | painter: BubblesPainter( 257 | currentProgress: _bubblesAnimation.value, 258 | color1: widget.bubblesColor.dotPrimaryColor, 259 | color2: widget.bubblesColor.dotSecondaryColor, 260 | color3: widget.bubblesColor.dotThirdColorReal, 261 | color4: widget.bubblesColor.dotLastColorReal, 262 | ), 263 | ), 264 | ), 265 | Positioned( 266 | top: (widget.size - widget.circleSize) / 2.0, 267 | left: (widget.size - widget.circleSize) / 2.0, 268 | child: CustomPaint( 269 | size: Size(widget.circleSize, widget.circleSize), 270 | painter: CirclePainter( 271 | innerCircleRadiusProgress: _innerCircleAnimation.value, 272 | outerCircleRadiusProgress: _outerCircleAnimation.value, 273 | circleColor: widget.circleColor, 274 | ), 275 | ), 276 | ), 277 | Container( 278 | width: widget.size, 279 | height: widget.size, 280 | alignment: Alignment.center, 281 | child: Transform.scale( 282 | scale: ((_isLiked ?? true) && _controller!.isAnimating) 283 | ? _scaleAnimation.value 284 | : 1.0, 285 | child: SizedBox( 286 | child: likeWidget, 287 | height: widget.size, 288 | width: widget.size, 289 | ), 290 | ), 291 | ), 292 | ], 293 | ); 294 | }, 295 | ), 296 | likeCountWidget 297 | ]; 298 | 299 | if (widget.countPostion == CountPostion.left || 300 | widget.countPostion == CountPostion.top) { 301 | children = children.reversed.toList(); 302 | } 303 | Widget result = (widget.countPostion == CountPostion.left || 304 | widget.countPostion == CountPostion.right) 305 | ? Row( 306 | mainAxisAlignment: widget.mainAxisAlignment, 307 | crossAxisAlignment: widget.crossAxisAlignment, 308 | children: children, 309 | ) 310 | : Column( 311 | mainAxisAlignment: widget.mainAxisAlignment, 312 | crossAxisAlignment: widget.crossAxisAlignment, 313 | children: children, 314 | ); 315 | 316 | if (widget.padding != null) { 317 | result = Padding( 318 | padding: widget.padding!, 319 | child: result, 320 | ); 321 | } 322 | 323 | return GestureDetector( 324 | behavior: HitTestBehavior.translucent, 325 | onTap: onTap, 326 | child: result, 327 | ); 328 | } 329 | 330 | Widget _getLikeCountWidget() { 331 | if (_likeCount == null) { 332 | return Container(); 333 | } 334 | final String likeCount = _likeCount.toString(); 335 | final String preLikeCount = _preLikeCount.toString(); 336 | 337 | int didIndex = 0; 338 | if (preLikeCount.length == likeCount.length) { 339 | for (; didIndex < likeCount.length; didIndex++) { 340 | if (likeCount[didIndex] != preLikeCount[didIndex]) { 341 | break; 342 | } 343 | } 344 | } 345 | final bool allChange = 346 | preLikeCount.length != likeCount.length || didIndex == 0; 347 | 348 | Widget result; 349 | 350 | if (widget.likeCountAnimationType == LikeCountAnimationType.none || 351 | _likeCount == _preLikeCount) { 352 | result = _createLikeCountWidget( 353 | _likeCount, _isLiked ?? true, _likeCount.toString()); 354 | } else if (widget.likeCountAnimationType == LikeCountAnimationType.part && 355 | !allChange) { 356 | final String samePart = likeCount.substring(0, didIndex); 357 | final String preText = 358 | preLikeCount.substring(didIndex, preLikeCount.length); 359 | final String text = likeCount.substring(didIndex, likeCount.length); 360 | final Widget preSameWidget = 361 | _createLikeCountWidget(_preLikeCount, !(_isLiked ?? true), samePart); 362 | final Widget currentSameWidget = 363 | _createLikeCountWidget(_likeCount, _isLiked ?? true, samePart); 364 | final Widget preWidget = 365 | _createLikeCountWidget(_preLikeCount, !(_isLiked ?? true), preText); 366 | final Widget currentWidget = 367 | _createLikeCountWidget(_likeCount, _isLiked ?? true, text); 368 | 369 | result = AnimatedBuilder( 370 | animation: _likeCountController!, 371 | builder: (BuildContext b, Widget? w) { 372 | return Directionality( 373 | textDirection: TextDirection.ltr, 374 | child: Row( 375 | mainAxisAlignment: MainAxisAlignment.center, 376 | crossAxisAlignment: CrossAxisAlignment.center, 377 | children: [ 378 | Stack( 379 | fit: StackFit.passthrough, 380 | clipBehavior: Clip.hardEdge, 381 | children: [ 382 | Opacity( 383 | child: currentSameWidget, 384 | opacity: _opacityAnimation.value, 385 | ), 386 | Opacity( 387 | child: preSameWidget, 388 | opacity: 1.0 - _opacityAnimation.value, 389 | ), 390 | ], 391 | ), 392 | Stack( 393 | fit: StackFit.passthrough, 394 | clipBehavior: Clip.hardEdge, 395 | children: [ 396 | FractionalTranslation( 397 | translation: _preLikeCount! > _likeCount! 398 | ? _slideCurrentValueAnimation.value 399 | : -_slideCurrentValueAnimation.value, 400 | child: currentWidget), 401 | FractionalTranslation( 402 | translation: _preLikeCount! > _likeCount! 403 | ? _slidePreValueAnimation.value 404 | : -_slidePreValueAnimation.value, 405 | child: preWidget), 406 | ], 407 | ) 408 | ], 409 | ), 410 | ); 411 | }); 412 | } else { 413 | result = AnimatedBuilder( 414 | animation: _likeCountController!, 415 | builder: (BuildContext b, Widget? w) { 416 | return Stack( 417 | fit: StackFit.passthrough, 418 | clipBehavior: Clip.hardEdge, 419 | children: [ 420 | FractionalTranslation( 421 | translation: _preLikeCount! > _likeCount! 422 | ? _slideCurrentValueAnimation.value 423 | : -_slideCurrentValueAnimation.value, 424 | child: _createLikeCountWidget( 425 | _likeCount, _isLiked ?? true, _likeCount.toString())), 426 | FractionalTranslation( 427 | translation: _preLikeCount! > _likeCount! 428 | ? _slidePreValueAnimation.value 429 | : -_slidePreValueAnimation.value, 430 | child: _createLikeCountWidget(_preLikeCount, 431 | !(_isLiked ?? true), _preLikeCount.toString())), 432 | ], 433 | ); 434 | }, 435 | ); 436 | } 437 | 438 | result = ClipRect( 439 | child: result, 440 | clipper: LikeCountClip(), 441 | ); 442 | 443 | return result; 444 | } 445 | 446 | Widget _createLikeCountWidget(int? likeCount, bool isLiked, String text) { 447 | return widget.countBuilder?.call(likeCount, isLiked, text) ?? 448 | Text(text, style: const TextStyle(color: Colors.grey)); 449 | } 450 | 451 | void onTap() { 452 | if (_controller!.isAnimating || _likeCountController!.isAnimating) { 453 | return; 454 | } 455 | if (widget.onTap != null) { 456 | widget.onTap!(_isLiked ?? true).then((bool? isLiked) { 457 | _handleIsLikeChanged(isLiked); 458 | }); 459 | } else { 460 | _handleIsLikeChanged(!(_isLiked ?? true)); 461 | } 462 | } 463 | 464 | void _handleIsLikeChanged(bool? isLiked) { 465 | if (_isLiked == null) { 466 | if (_likeCount != null) { 467 | _preLikeCount = _likeCount; 468 | _likeCount = _likeCount! + 1; 469 | } 470 | if (mounted) { 471 | setState(() { 472 | _controller!.reset(); 473 | _controller!.forward(); 474 | 475 | if (widget.likeCountAnimationType != LikeCountAnimationType.none) { 476 | _likeCountController!.reset(); 477 | _likeCountController!.forward(); 478 | } 479 | }); 480 | } 481 | return; 482 | } 483 | 484 | if (isLiked != null && isLiked != _isLiked) { 485 | if (_likeCount != null) { 486 | _preLikeCount = _likeCount; 487 | if (isLiked) { 488 | _likeCount = _likeCount! + 1; 489 | } else { 490 | _likeCount = _likeCount! - 1; 491 | } 492 | } 493 | _isLiked = isLiked; 494 | 495 | if (mounted) { 496 | setState(() { 497 | if (_isLiked!) { 498 | _controller!.reset(); 499 | _controller!.forward(); 500 | } 501 | if (widget.likeCountAnimationType != LikeCountAnimationType.none) { 502 | _likeCountController!.reset(); 503 | _likeCountController!.forward(); 504 | } 505 | }); 506 | } 507 | } 508 | } 509 | 510 | void _initAnimations() { 511 | _initControlAnimation(); 512 | _initLikeCountControllerAnimation(); 513 | } 514 | 515 | void _initLikeCountControllerAnimation() { 516 | _slidePreValueAnimation = _likeCountController!.drive(Tween( 517 | begin: Offset.zero, 518 | end: const Offset(0.0, 1.0), 519 | )); 520 | _slideCurrentValueAnimation = _likeCountController!.drive(Tween( 521 | begin: const Offset(0.0, -1.0), 522 | end: Offset.zero, 523 | )); 524 | 525 | _opacityAnimation = _likeCountController!.drive(Tween( 526 | begin: 0.0, 527 | end: 1.0, 528 | )); 529 | } 530 | 531 | void _initControlAnimation() { 532 | _outerCircleAnimation = Tween( 533 | begin: 0.1, 534 | end: 1.0, 535 | ).animate( 536 | CurvedAnimation( 537 | parent: _controller!, 538 | curve: const Interval( 539 | 0.0, 540 | 0.3, 541 | curve: Curves.ease, 542 | ), 543 | ), 544 | ); 545 | _innerCircleAnimation = Tween( 546 | begin: 0.2, 547 | end: 1.0, 548 | ).animate( 549 | CurvedAnimation( 550 | parent: _controller!, 551 | curve: const Interval( 552 | 0.2, 553 | 0.5, 554 | curve: Curves.ease, 555 | ), 556 | ), 557 | ); 558 | final Animation animate = Tween( 559 | begin: 0.2, 560 | end: 1.0, 561 | ).animate( 562 | CurvedAnimation( 563 | parent: _controller!, 564 | curve: const Interval( 565 | 0.35, 566 | 0.7, 567 | curve: OvershootCurve(), 568 | ), 569 | ), 570 | ); 571 | _scaleAnimation = animate; 572 | _bubblesAnimation = Tween( 573 | begin: 0.0, 574 | end: 1.0, 575 | ).animate( 576 | CurvedAnimation( 577 | parent: _controller!, 578 | curve: const Interval( 579 | 0.1, 580 | 1.0, 581 | curve: Curves.decelerate, 582 | ), 583 | ), 584 | ); 585 | } 586 | } 587 | -------------------------------------------------------------------------------- /lib/src/painter/bubbles_painter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' as math; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'package:like_button/src/utils/like_button_util.dart'; 6 | 7 | /// 8 | /// create by zmtzawqlp on 2019/5/27 9 | /// 10 | 11 | class BubblesPainter extends CustomPainter { 12 | BubblesPainter({ 13 | required this.currentProgress, 14 | this.bubblesCount = 7, 15 | this.color1 = const Color(0xFFFFC107), 16 | this.color2 = const Color(0xFFFF9800), 17 | this.color3 = const Color(0xFFFF5722), 18 | this.color4 = const Color(0xFFF44336), 19 | }) { 20 | _outerBubblesPositionAngle = 360.0 / bubblesCount; 21 | for (int i = 0; i < 4; i++) { 22 | _circlePaints.add(Paint()..style = PaintingStyle.fill); 23 | } 24 | } 25 | final double currentProgress; 26 | final int bubblesCount; 27 | final Color color1; 28 | final Color color2; 29 | final Color color3; 30 | final Color color4; 31 | 32 | double _outerBubblesPositionAngle = 51.42; 33 | double _centerX = 0.0; 34 | double _centerY = 0.0; 35 | final List _circlePaints = []; 36 | 37 | double _maxOuterDotsRadius = 0.0; 38 | double _maxInnerDotsRadius = 0.0; 39 | double? _maxDotSize; 40 | 41 | double _currentRadius1 = 0.0; 42 | double? _currentDotSize1 = 0.0; 43 | double? _currentDotSize2 = 0.0; 44 | double _currentRadius2 = 0.0; 45 | 46 | @override 47 | void paint(Canvas canvas, Size size) { 48 | _centerX = size.width * 0.5; 49 | _centerY = size.height * 0.5; 50 | _maxDotSize = size.width * 0.05; 51 | _maxOuterDotsRadius = size.width * 0.5 - _maxDotSize! * 2; 52 | _maxInnerDotsRadius = 0.8 * _maxOuterDotsRadius; 53 | 54 | _updateOuterBubblesPosition(); 55 | _updateInnerBubblesPosition(); 56 | _updateBubblesPaints(); 57 | _drawOuterBubblesFrame(canvas); 58 | _drawInnerBubblesFrame(canvas); 59 | } 60 | 61 | void _drawOuterBubblesFrame(Canvas canvas) { 62 | final double start = _outerBubblesPositionAngle / 4.0 * 3.0; 63 | for (int i = 0; i < bubblesCount; i++) { 64 | final double cX = _centerX + 65 | _currentRadius1 * 66 | math.cos(degToRad(start + _outerBubblesPositionAngle * i)); 67 | final double cY = _centerY + 68 | _currentRadius1 * 69 | math.sin(degToRad(start + _outerBubblesPositionAngle * i)); 70 | canvas.drawCircle(Offset(cX, cY), _currentDotSize1!, 71 | _circlePaints[i % _circlePaints.length]); 72 | } 73 | } 74 | 75 | void _drawInnerBubblesFrame(Canvas canvas) { 76 | final double start = _outerBubblesPositionAngle / 4.0 * 3.0 - 77 | _outerBubblesPositionAngle / 2.0; 78 | for (int i = 0; i < bubblesCount; i++) { 79 | final double cX = _centerX + 80 | _currentRadius2 * 81 | math.cos(degToRad(start + _outerBubblesPositionAngle * i)); 82 | final double cY = _centerY + 83 | _currentRadius2 * 84 | math.sin(degToRad(start + _outerBubblesPositionAngle * i)); 85 | canvas.drawCircle(Offset(cX, cY), _currentDotSize2!, 86 | _circlePaints[(i + 1) % _circlePaints.length]); 87 | } 88 | } 89 | 90 | void _updateOuterBubblesPosition() { 91 | if (currentProgress < 0.3) { 92 | _currentRadius1 = mapValueFromRangeToRange( 93 | currentProgress, 0.0, 0.3, 0.0, _maxOuterDotsRadius * 0.8); 94 | } else { 95 | _currentRadius1 = mapValueFromRangeToRange(currentProgress, 0.3, 1.0, 96 | 0.8 * _maxOuterDotsRadius, _maxOuterDotsRadius); 97 | } 98 | if (currentProgress == 0) { 99 | _currentDotSize1 = 0; 100 | } else if (currentProgress < 0.7) { 101 | _currentDotSize1 = _maxDotSize; 102 | } else { 103 | _currentDotSize1 = mapValueFromRangeToRange( 104 | currentProgress, 0.7, 1.0, _maxDotSize!, 0.0); 105 | } 106 | } 107 | 108 | void _updateInnerBubblesPosition() { 109 | if (currentProgress < 0.3) { 110 | _currentRadius2 = mapValueFromRangeToRange( 111 | currentProgress, 0.0, 0.3, 0.0, _maxInnerDotsRadius); 112 | } else { 113 | _currentRadius2 = _maxInnerDotsRadius; 114 | } 115 | if (currentProgress == 0) { 116 | _currentDotSize2 = 0; 117 | } else if (currentProgress < 0.2) { 118 | _currentDotSize2 = _maxDotSize; 119 | } else if (currentProgress < 0.5) { 120 | _currentDotSize2 = mapValueFromRangeToRange( 121 | currentProgress, 0.2, 0.5, _maxDotSize!, 0.3 * _maxDotSize!); 122 | } else { 123 | _currentDotSize2 = mapValueFromRangeToRange( 124 | currentProgress, 0.5, 1.0, _maxDotSize! * 0.3, 0.0); 125 | } 126 | } 127 | 128 | void _updateBubblesPaints() { 129 | final double progress = clamp(currentProgress, 0.6, 1.0); 130 | final int alpha = 131 | mapValueFromRangeToRange(progress, 0.6, 1.0, 255.0, 0.0).toInt(); 132 | if (currentProgress < 0.5) { 133 | final double progress = 134 | mapValueFromRangeToRange(currentProgress, 0.0, 0.5, 0.0, 1.0); 135 | _circlePaints[0].color = 136 | Color.lerp(color1, color2, progress)!.withAlpha(alpha); 137 | _circlePaints[1].color = 138 | Color.lerp(color2, color3, progress)!.withAlpha(alpha); 139 | _circlePaints[2].color = 140 | Color.lerp(color3, color4, progress)!.withAlpha(alpha); 141 | _circlePaints[3].color = 142 | Color.lerp(color4, color1, progress)!.withAlpha(alpha); 143 | } else { 144 | final double progress = 145 | mapValueFromRangeToRange(currentProgress, 0.5, 1.0, 0.0, 1.0); 146 | _circlePaints[0].color = 147 | Color.lerp(color2, color3, progress)!.withAlpha(alpha); 148 | _circlePaints[1].color = 149 | Color.lerp(color3, color4, progress)!.withAlpha(alpha); 150 | _circlePaints[2].color = 151 | Color.lerp(color4, color1, progress)!.withAlpha(alpha); 152 | _circlePaints[3].color = 153 | Color.lerp(color1, color2, progress)!.withAlpha(alpha); 154 | } 155 | } 156 | 157 | @override 158 | bool shouldRepaint(CustomPainter oldDelegate) { 159 | if (oldDelegate.runtimeType != runtimeType) { 160 | return true; 161 | } 162 | 163 | return oldDelegate is BubblesPainter && 164 | (oldDelegate.bubblesCount != bubblesCount || 165 | oldDelegate.currentProgress != currentProgress || 166 | oldDelegate.color1 != color1 || 167 | oldDelegate.color2 != color2 || 168 | oldDelegate.color3 != color3 || 169 | oldDelegate.color4 != color4); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /lib/src/painter/circle_painter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:like_button/src/utils/like_button_model.dart'; 3 | import 'package:like_button/src/utils/like_button_util.dart'; 4 | 5 | /// 6 | /// create by zmtzawqlp on 2019/5/27 7 | /// 8 | 9 | class CirclePainter extends CustomPainter { 10 | CirclePainter( 11 | {required this.outerCircleRadiusProgress, 12 | required this.innerCircleRadiusProgress, 13 | this.circleColor = const CircleColor( 14 | start: Color(0xFFFF5722), end: Color(0xFFFFC107))}) { 15 | //circlePaint..style = PaintingStyle.fill; 16 | _circlePaint.style = PaintingStyle.stroke; 17 | //maskPaint..blendMode = BlendMode.clear; 18 | } 19 | final Paint _circlePaint = Paint(); 20 | //Paint maskPaint = new Paint(); 21 | 22 | final double outerCircleRadiusProgress; 23 | final double innerCircleRadiusProgress; 24 | final CircleColor circleColor; 25 | 26 | @override 27 | void paint(Canvas canvas, Size size) { 28 | final double center = size.width * 0.5; 29 | _updateCircleColor(); 30 | // canvas.saveLayer(Offset.zero & size, Paint()); 31 | // canvas.drawCircle(Offset(center, center), 32 | // outerCircleRadiusProgress * center, circlePaint); 33 | // canvas.drawCircle(Offset(center, center), 34 | // innerCircleRadiusProgress * center + 1, maskPaint); 35 | // canvas.restore(); 36 | //flutter web don't support BlendMode.clear. 37 | final double strokeWidth = outerCircleRadiusProgress * center - 38 | (innerCircleRadiusProgress * center); 39 | if (strokeWidth > 0.0) { 40 | _circlePaint.strokeWidth = strokeWidth; 41 | canvas.drawCircle(Offset(center, center), 42 | outerCircleRadiusProgress * center, _circlePaint); 43 | } 44 | } 45 | 46 | void _updateCircleColor() { 47 | double colorProgress = clamp(outerCircleRadiusProgress, 0.5, 1.0); 48 | colorProgress = mapValueFromRangeToRange(colorProgress, 0.5, 1.0, 0.0, 1.0); 49 | _circlePaint.color = 50 | Color.lerp(circleColor.start, circleColor.end, colorProgress)!; 51 | } 52 | 53 | @override 54 | bool shouldRepaint(CustomPainter oldDelegate) { 55 | if (oldDelegate.runtimeType != runtimeType) { 56 | return true; 57 | } 58 | 59 | return oldDelegate is CirclePainter && 60 | (oldDelegate.outerCircleRadiusProgress != outerCircleRadiusProgress || 61 | oldDelegate.innerCircleRadiusProgress != 62 | innerCircleRadiusProgress || 63 | oldDelegate.circleColor.start != circleColor.start || 64 | oldDelegate.circleColor.end != circleColor.end); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/src/utils/like_button_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 4 | /// create by zmtzawqlp on 2019/5/27 5 | /// 6 | 7 | class BubblesColor { 8 | const BubblesColor({ 9 | required this.dotPrimaryColor, 10 | required this.dotSecondaryColor, 11 | this.dotThirdColor, 12 | this.dotLastColor, 13 | }); 14 | final Color dotPrimaryColor; 15 | final Color dotSecondaryColor; 16 | final Color? dotThirdColor; 17 | final Color? dotLastColor; 18 | Color get dotThirdColorReal => dotThirdColor ?? dotPrimaryColor; 19 | 20 | Color get dotLastColorReal => dotLastColor ?? dotSecondaryColor; 21 | } 22 | 23 | class CircleColor { 24 | const CircleColor({ 25 | required this.start, 26 | required this.end, 27 | }); 28 | final Color start; 29 | final Color end; 30 | } 31 | 32 | class OvershootCurve extends Curve { 33 | const OvershootCurve([this.period = 2.5]); 34 | 35 | final double period; 36 | 37 | @override 38 | double transform(double t) { 39 | assert(t >= 0.0 && t <= 1.0); 40 | t -= 1.0; 41 | return t * t * ((period + 1) * t + period) + 1.0; 42 | } 43 | 44 | @override 45 | String toString() { 46 | return '$runtimeType($period)'; 47 | } 48 | } 49 | 50 | class LikeCountClip extends CustomClipper { 51 | @override 52 | Rect getClip(Size size) { 53 | return Offset.zero & size; 54 | } 55 | 56 | @override 57 | bool shouldReclip(CustomClipper oldClipper) { 58 | return true; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/src/utils/like_button_typedef.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 4 | /// create by zmtzawqlp on 2019/5/27 5 | /// 6 | 7 | /// tap call back 8 | /// you can send your request here 9 | /// if failed, return null 10 | /// 11 | typedef LikeButtonTapCallback = Future Function(bool isLiked); 12 | 13 | ///build widget when isLike is changing 14 | typedef LikeWidgetBuilder = Widget? Function(bool isLiked); 15 | 16 | ///build widget when likeCount is changing 17 | typedef LikeCountWidgetBuilder = Widget? Function( 18 | int? likeCount, 19 | bool isLiked, 20 | String text, 21 | ); 22 | 23 | enum LikeCountAnimationType { 24 | //no animation 25 | none, 26 | //animation only on change part 27 | part, 28 | //animation on all 29 | all, 30 | } 31 | 32 | ///like count widget postion 33 | ///left of like widget 34 | ///right of like widget 35 | enum CountPostion { 36 | left, 37 | right, 38 | top, 39 | bottom, 40 | } 41 | 42 | ///return count widget with decoration 43 | typedef CountDecoration = Widget? Function( 44 | Widget count, 45 | int? likeCount, 46 | ); 47 | -------------------------------------------------------------------------------- /lib/src/utils/like_button_util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' as math; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// create by zmtzawqlp on 2019/5/27 7 | /// 8 | num degToRad(num deg) => deg * (math.pi / 180.0); 9 | 10 | num radToDeg(num rad) => rad * (180.0 / math.pi); 11 | 12 | double mapValueFromRangeToRange(double value, double fromLow, double fromHigh, 13 | double toLow, double toHigh) { 14 | return toLow + ((value - fromLow) / (fromHigh - fromLow) * (toHigh - toLow)); 15 | } 16 | 17 | double clamp(double value, double low, double high) { 18 | return math.min(math.max(value, low), high); 19 | } 20 | 21 | Widget defaultWidgetBuilder(bool isLiked, double size) { 22 | return Icon( 23 | Icons.favorite, 24 | color: isLiked ? Colors.pinkAccent : Colors.grey, 25 | size: size, 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: like_button 2 | description: Like Button is a flutter library that allows you to create a button with animation effects similar to Twitter's heart when you like something. 3 | version: 2.1.0 4 | homepage: https://github.com/fluttercandies/like_button 5 | 6 | environment: 7 | sdk: '>=2.12.0 <3.0.0' 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | dev_dependencies: 14 | flutter_test: 15 | sdk: flutter 16 | 17 | # For information on the generic Dart part of this file, see the 18 | # following page: https://www.dartlang.org/tools/pub/pubspec 19 | 20 | # The following section is specific to Flutter. 21 | flutter: 22 | 23 | # To add assets to your package, add an assets section, like this: 24 | # assets: 25 | # - images/a_dot_burr.jpeg 26 | # - images/a_dot_ham.jpeg 27 | # 28 | # For details regarding assets in packages, see 29 | # https://flutter.dev/assets-and-images/#from-packages 30 | # 31 | # An image asset can refer to one or more resolution-specific "variants", see 32 | # https://flutter.dev/assets-and-images/#resolution-aware. 33 | 34 | # To add custom fonts to your package, add a fonts section here, 35 | # in this "flutter" section. Each entry in this list should have a 36 | # "family" key with the font family name, and a "fonts" key with a 37 | # list giving the asset and other descriptors for the font. For 38 | # example: 39 | # fonts: 40 | # - family: Schyler 41 | # fonts: 42 | # - asset: fonts/Schyler-Regular.ttf 43 | # - asset: fonts/Schyler-Italic.ttf 44 | # style: italic 45 | # - family: Trajan Pro 46 | # fonts: 47 | # - asset: fonts/TrajanPro.ttf 48 | # - asset: fonts/TrajanPro_Bold.ttf 49 | # weight: 700 50 | # 51 | # For details regarding fonts in packages, see 52 | # https://flutter.dev/custom-fonts/#from-packages 53 | --------------------------------------------------------------------------------