├── .gitignore ├── .metadata ├── LICENSE ├── README.md ├── android ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── chessluo │ │ │ │ └── flutter_study_app │ │ │ │ ├── MainActivity.java │ │ │ │ └── MyMethodChannel.java │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── logo.jpg │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values │ │ │ └── styles.xml │ │ │ └── xml │ │ │ └── network_security_config.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets └── images │ └── logo.jpg ├── ios ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── main.m ├── lib ├── common │ ├── constant.dart │ ├── events.dart │ └── model │ │ └── func_model.dart ├── fl_app.dart ├── main.dart ├── pages │ ├── anim │ │ ├── anim_page.dart │ │ └── basis_canvas_page.dart │ ├── cache │ │ ├── demo │ │ │ ├── preferences_demo.dart │ │ │ └── sqflite_demo.dart │ │ └── local_cache_page.dart │ ├── channel │ │ └── flutter_channel_demo.dart │ ├── dart │ │ └── dart_page.dart │ ├── main │ │ ├── about_page.dart │ │ ├── drawer_page.dart │ │ ├── home_page.dart │ │ └── main_page.dart │ ├── other │ │ ├── demo │ │ │ ├── event_bus_demo.dart │ │ │ ├── file_zip_demo.dart │ │ │ ├── flutter_webview_demo.dart │ │ │ ├── url_launcher_demo.dart │ │ │ └── webview_plugin_demo.dart │ │ └── other_page.dart │ ├── state │ │ ├── provider_demo │ │ │ ├── navigationbar_model.dart │ │ │ └── provider_demo.dart │ │ └── state_page.dart │ ├── transition_page.dart │ └── widgets │ │ └── widgets_page.dart ├── provider │ └── color_filtered_model.dart ├── res │ ├── colors.dart │ └── string_zh.dart ├── routers │ ├── application.dart │ ├── router_handler.dart │ └── routers.dart └── utils │ ├── object_util.dart │ └── toast_util.dart ├── pubspec.lock ├── pubspec.yaml ├── screenshots ├── about.png ├── channel.gif ├── drawer.png ├── gfone.gif ├── gray.gif ├── main.png ├── myQrcode.jpg ├── other.png ├── router.gif ├── shared_preferences.gif ├── sqflite.png ├── url_launcher.gif ├── webview.gif └── zip.png └── test └── widget_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | .flutter-plugins-dependencies 30 | **/ios/Flutter/.last_build_id 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/flutter_export_environment.sh 62 | **/ios/Flutter/app.flx 63 | **/ios/Flutter/app.zip 64 | **/ios/Flutter/flutter_assets/ 65 | **/ios/ServiceDefinitions.json 66 | **/ios/Runner/GeneratedPluginRegistrant.* 67 | 68 | # Exceptions to above rules. 69 | !**/ios/**/default.mode1v3 70 | !**/ios/**/default.mode2v3 71 | !**/ios/**/default.pbxuser 72 | !**/ios/**/default.perspectivev3 73 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 74 | 75 | # Android Studio will place build artifacts here 76 | /android/app/debug 77 | /android/app/profile 78 | /android/app/release 79 | 80 | # Web related 81 | lib/generated_plugin_registrant.dart 82 | 83 | # Symbolication related 84 | app.*.symbols 85 | 86 | # Obfuscation related 87 | app.*.map.json -------------------------------------------------------------------------------- /.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: 8661d8aecd626f7f57ccbcb735553edc05a2e713 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 项目简介 2 | 3 | A new Flutter application. 4 | 我希望能利用业余时间去学习及总结一些有关flutter的知识并运用到项目中去,Come on!!! 5 | 6 | ## Flutter相关网站 7 | * [Google/flutter](https://github.com/flutter/flutter) 8 | * [flutter中文官网](https://flutter.cn/) 9 | * [pub.flutter](https://pub.flutter-io.cn/) 10 | * [dart中文官网](https://dart.cn/) 11 | 12 | 13 | ## 样式效果演示 14 | |主页|drawer|关于| 15 | |:---:|:---:|:---:| 16 | |||| 17 | 18 | 19 | |其他Demo|修改主题色|解压缩插件| 20 | |:---:|:---:|:---:| 21 | |||| 22 | 23 | |flutterWebviewPlugin|fluro路由|shared_preferences| 24 | |:---:|:---:|:---:| 25 | |||| 26 | 27 | |sqflite数据库|flutter channel|flutter url_launcher| 28 | |:---:|:---:|:---:| 29 | |||| 30 | 31 | |全局变灰||| 32 | |:---:|:---:|:---:| 33 | |||| 34 | 35 | 36 | |Dart| 37 | |:---:| 38 | |功能demo开发中~| 39 | 40 | |Widgets| 41 | |:---:| 42 | |功能demo开发中~| 43 | 44 | |Api| 45 | |:---:| 46 | |功能demo开发中~| 47 | 48 | ## 更多 49 | * 更多开源库请关注:[GitHub](https://github.com/ChessLuo) 50 | * 最近建了公众号,欢迎大家关注,一起学习Android、小程序、跨平台开发~ 51 | * ![](screenshots/myQrcode.jpg) -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 30 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.chessluo.flutter_study_app" 37 | minSdkVersion 19 38 | targetSdkVersion 30 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 42 | 43 | // ndk { 44 | // abiFilters "armeabi-v7a","x86_64","armeabi","mips" 45 | // } 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 | testImplementation 'junit:junit:4.12' 63 | androidTestImplementation 'androidx.test:runner:1.1.0' 64 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 65 | } 66 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | 13 | 19 | 26 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/chessluo/flutter_study_app/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.chessluo.flutter_study_app; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | import io.flutter.plugin.common.PluginRegistry; 7 | /** 8 | * @描述 Flutter android主页 9 | * @author chessluo 10 | * @email superluo666@gmail.com 11 | * @date 2019-08-11 12 | * 13 | */ 14 | 15 | public class MainActivity extends FlutterActivity { 16 | 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | GeneratedPluginRegistrant.registerWith(this); 22 | 23 | registerCustomPlugin(this); 24 | } 25 | 26 | private void registerCustomPlugin(PluginRegistry registrar) { 27 | MyMethodChannel.registerWith(registrar.registrarFor(MyMethodChannel.CHANNEL)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/chessluo/flutter_study_app/MyMethodChannel.java: -------------------------------------------------------------------------------- 1 | package com.chessluo.flutter_study_app; 2 | 3 | import android.app.Activity; 4 | import android.content.ContextWrapper; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.os.BatteryManager; 8 | import android.os.Build; 9 | 10 | import io.flutter.plugin.common.MethodCall; 11 | import io.flutter.plugin.common.MethodChannel; 12 | import io.flutter.plugin.common.PluginRegistry; 13 | 14 | /** 15 | * @author ChessLuo 16 | * @描述 flutter channel Android通道交互 17 | * @email superluo666@gmail.com 18 | * @date 2019-08-11 19 | */ 20 | public class MyMethodChannel implements MethodChannel.MethodCallHandler { 21 | 22 | 23 | public static String CHANNEL = "flutter_study_app"; 24 | 25 | static MethodChannel mMethodChannel; 26 | 27 | private PluginRegistry.Registrar mRegistrar; 28 | private Activity mActivity; 29 | 30 | private MyMethodChannel(PluginRegistry.Registrar registrar) { 31 | mRegistrar = registrar; 32 | mActivity = registrar.activity(); 33 | } 34 | 35 | public static void registerWith(PluginRegistry.Registrar registrar) { 36 | mMethodChannel = new MethodChannel(registrar.messenger(), CHANNEL); 37 | MyMethodChannel instance = new MyMethodChannel(registrar); 38 | //setMethodCallHandler在此通道上接收方法调用的回调 39 | mMethodChannel.setMethodCallHandler(instance); 40 | } 41 | 42 | 43 | @Override 44 | public void onMethodCall(MethodCall call, MethodChannel.Result result) { 45 | if (call.method.equals("getBatteryLevel")) { 46 | int batteryLevel = getBatteryLevel(); 47 | 48 | if (batteryLevel != -1) { 49 | result.success(batteryLevel); 50 | } else { 51 | result.error("UNAVAILABLE", "Battery level not available.", null); 52 | } 53 | } else { 54 | result.notImplemented(); 55 | } 56 | } 57 | 58 | 59 | 60 | /**获取电量*/ 61 | private int getBatteryLevel() { 62 | int batteryLevel = -1; 63 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 64 | BatteryManager batteryManager = (BatteryManager) mRegistrar.context().getSystemService(mRegistrar.context().BATTERY_SERVICE); 65 | batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); 66 | } else { 67 | Intent intent = new ContextWrapper(mRegistrar.context()). 68 | registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 69 | batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) / 70 | intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); 71 | } 72 | 73 | return batteryLevel; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/android/app/src/main/res/mipmap-hdpi/logo.jpg -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:4.1.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Mar 21 10:55:04 CST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/assets/images/logo.jpg -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 37 | # referring to absolute paths on developers' machines. 38 | system('rm -rf .symlinks') 39 | system('mkdir -p .symlinks/plugins') 40 | 41 | # Flutter Pods 42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 43 | if generated_xcode_build_settings.empty? 44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first." 45 | end 46 | generated_xcode_build_settings.map { |p| 47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 48 | symlink = File.join('.symlinks', 'flutter') 49 | File.symlink(File.dirname(p[:path]), symlink) 50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 51 | end 52 | } 53 | 54 | # Plugin Pods 55 | plugin_pods = parse_KV_file('../.flutter-plugins') 56 | plugin_pods.map { |p| 57 | symlink = File.join('.symlinks', 'plugins', p[:name]) 58 | File.symlink(p[:path], symlink) 59 | pod p[:name], :path => File.join(symlink, 'ios') 60 | } 61 | end 62 | 63 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 64 | install! 'cocoapods', :disable_input_output_paths => true 65 | 66 | post_install do |installer| 67 | installer.pods_project.targets.each do |target| 68 | target.build_configurations.each do |config| 69 | config.build_settings['ENABLE_BITCODE'] = 'NO' 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - flutter_webview_plugin (0.0.1): 4 | - Flutter 5 | - fluttertoast (0.0.2): 6 | - Flutter 7 | - FMDB (2.7.5): 8 | - FMDB/standard (= 2.7.5) 9 | - FMDB/standard (2.7.5) 10 | - path_provider (0.0.1): 11 | - Flutter 12 | - permission_handler (3.1.0): 13 | - Flutter 14 | - shared_preferences (0.0.1): 15 | - Flutter 16 | - sqflite (0.0.1): 17 | - Flutter 18 | - FMDB (~> 2.7.2) 19 | - url_launcher (0.0.1): 20 | - Flutter 21 | - webview_flutter (0.0.1): 22 | - Flutter 23 | 24 | DEPENDENCIES: 25 | - Flutter (from `.symlinks/flutter/ios`) 26 | - flutter_webview_plugin (from `.symlinks/plugins/flutter_webview_plugin/ios`) 27 | - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) 28 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 29 | - permission_handler (from `.symlinks/plugins/permission_handler/ios`) 30 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) 31 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 32 | - url_launcher (from `.symlinks/plugins/url_launcher/ios`) 33 | - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) 34 | 35 | SPEC REPOS: 36 | https://github.com/cocoapods/specs.git: 37 | - FMDB 38 | 39 | EXTERNAL SOURCES: 40 | Flutter: 41 | :path: ".symlinks/flutter/ios" 42 | flutter_webview_plugin: 43 | :path: ".symlinks/plugins/flutter_webview_plugin/ios" 44 | fluttertoast: 45 | :path: ".symlinks/plugins/fluttertoast/ios" 46 | path_provider: 47 | :path: ".symlinks/plugins/path_provider/ios" 48 | permission_handler: 49 | :path: ".symlinks/plugins/permission_handler/ios" 50 | shared_preferences: 51 | :path: ".symlinks/plugins/shared_preferences/ios" 52 | sqflite: 53 | :path: ".symlinks/plugins/sqflite/ios" 54 | url_launcher: 55 | :path: ".symlinks/plugins/url_launcher/ios" 56 | webview_flutter: 57 | :path: ".symlinks/plugins/webview_flutter/ios" 58 | 59 | SPEC CHECKSUMS: 60 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec 61 | flutter_webview_plugin: ed9e8a6a96baf0c867e90e1bce2673913eeac694 62 | fluttertoast: b644586ef3b16f67fae9a1f8754cef6b2d6b634b 63 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 64 | path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259 65 | permission_handler: fa6b0d784b1a43cb96b468a5b8365cb130b1956a 66 | shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523 67 | sqflite: ff1d9da63c06588cc8d1faf7256d741f16989d5a 68 | url_launcher: a1c0cc845906122c4784c542523d8cacbded5626 69 | webview_flutter: bec7599de6bfbe8008a739aa3ebd7b364ea9d0cd 70 | 71 | PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932 72 | 73 | COCOAPODS: 1.7.1 74 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 15 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 17 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 18 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 19 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 20 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 21 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 22 | FD74DF95AE6BE945472BE696 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BBFF6FA46C48056A7E41E7AB /* libPods-Runner.a */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXCopyFilesBuildPhase section */ 26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 27 | isa = PBXCopyFilesBuildPhase; 28 | buildActionMask = 2147483647; 29 | dstPath = ""; 30 | dstSubfolderSpec = 10; 31 | files = ( 32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 34 | ); 35 | name = "Embed Frameworks"; 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | /* End PBXCopyFilesBuildPhase section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 42 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 43 | 2109599CA91BADD15841971B /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 46 | 6A7AAC3BC88E1B94F19ED923 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 47 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 48 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 49 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 50 | 96AE66592F3CBB08E7520D62 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 51 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 52 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 53 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 54 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 56 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 57 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 58 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 59 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | BBFF6FA46C48056A7E41E7AB /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 69 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 70 | FD74DF95AE6BE945472BE696 /* libPods-Runner.a in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | /* End PBXFrameworksBuildPhase section */ 75 | 76 | /* Begin PBXGroup section */ 77 | 300AF6292F6ECA69E128A81E /* Pods */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 2109599CA91BADD15841971B /* Pods-Runner.debug.xcconfig */, 81 | 6A7AAC3BC88E1B94F19ED923 /* Pods-Runner.release.xcconfig */, 82 | 96AE66592F3CBB08E7520D62 /* Pods-Runner.profile.xcconfig */, 83 | ); 84 | name = Pods; 85 | path = Pods; 86 | sourceTree = ""; 87 | }; 88 | 9740EEB11CF90186004384FC /* Flutter */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 3B80C3931E831B6300D905FE /* App.framework */, 92 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 93 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 94 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 95 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 96 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 97 | ); 98 | name = Flutter; 99 | sourceTree = ""; 100 | }; 101 | 97C146E51CF9000F007C117D = { 102 | isa = PBXGroup; 103 | children = ( 104 | 9740EEB11CF90186004384FC /* Flutter */, 105 | 97C146F01CF9000F007C117D /* Runner */, 106 | 97C146EF1CF9000F007C117D /* Products */, 107 | 300AF6292F6ECA69E128A81E /* Pods */, 108 | C41F993EABC10CBC53AEE6D9 /* Frameworks */, 109 | ); 110 | sourceTree = ""; 111 | }; 112 | 97C146EF1CF9000F007C117D /* Products */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 97C146EE1CF9000F007C117D /* Runner.app */, 116 | ); 117 | name = Products; 118 | sourceTree = ""; 119 | }; 120 | 97C146F01CF9000F007C117D /* Runner */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 124 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 125 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 126 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 127 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 128 | 97C147021CF9000F007C117D /* Info.plist */, 129 | 97C146F11CF9000F007C117D /* Supporting Files */, 130 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 131 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 132 | ); 133 | path = Runner; 134 | sourceTree = ""; 135 | }; 136 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 97C146F21CF9000F007C117D /* main.m */, 140 | ); 141 | name = "Supporting Files"; 142 | sourceTree = ""; 143 | }; 144 | C41F993EABC10CBC53AEE6D9 /* Frameworks */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | BBFF6FA46C48056A7E41E7AB /* libPods-Runner.a */, 148 | ); 149 | name = Frameworks; 150 | sourceTree = ""; 151 | }; 152 | /* End PBXGroup section */ 153 | 154 | /* Begin PBXNativeTarget section */ 155 | 97C146ED1CF9000F007C117D /* Runner */ = { 156 | isa = PBXNativeTarget; 157 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 158 | buildPhases = ( 159 | 45A88905D38BFF9D02FDAF6D /* [CP] Check Pods Manifest.lock */, 160 | 9740EEB61CF901F6004384FC /* Run Script */, 161 | 97C146EA1CF9000F007C117D /* Sources */, 162 | 97C146EB1CF9000F007C117D /* Frameworks */, 163 | 97C146EC1CF9000F007C117D /* Resources */, 164 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 165 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 166 | D7B4D54AA176674C5A38B2A1 /* [CP] Embed Pods Frameworks */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | ); 172 | name = Runner; 173 | productName = Runner; 174 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 175 | productType = "com.apple.product-type.application"; 176 | }; 177 | /* End PBXNativeTarget section */ 178 | 179 | /* Begin PBXProject section */ 180 | 97C146E61CF9000F007C117D /* Project object */ = { 181 | isa = PBXProject; 182 | attributes = { 183 | LastUpgradeCheck = 0910; 184 | ORGANIZATIONNAME = "The Chromium Authors"; 185 | TargetAttributes = { 186 | 97C146ED1CF9000F007C117D = { 187 | CreatedOnToolsVersion = 7.3.1; 188 | }; 189 | }; 190 | }; 191 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 192 | compatibilityVersion = "Xcode 3.2"; 193 | developmentRegion = English; 194 | hasScannedForEncodings = 0; 195 | knownRegions = ( 196 | en, 197 | Base, 198 | ); 199 | mainGroup = 97C146E51CF9000F007C117D; 200 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 201 | projectDirPath = ""; 202 | projectRoot = ""; 203 | targets = ( 204 | 97C146ED1CF9000F007C117D /* Runner */, 205 | ); 206 | }; 207 | /* End PBXProject section */ 208 | 209 | /* Begin PBXResourcesBuildPhase section */ 210 | 97C146EC1CF9000F007C117D /* Resources */ = { 211 | isa = PBXResourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 215 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 216 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 217 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 218 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | /* End PBXResourcesBuildPhase section */ 223 | 224 | /* Begin PBXShellScriptBuildPhase section */ 225 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputPaths = ( 231 | ); 232 | name = "Thin Binary"; 233 | outputPaths = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | shellPath = /bin/sh; 237 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 238 | }; 239 | 45A88905D38BFF9D02FDAF6D /* [CP] Check Pods Manifest.lock */ = { 240 | isa = PBXShellScriptBuildPhase; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | ); 244 | inputFileListPaths = ( 245 | ); 246 | inputPaths = ( 247 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 248 | "${PODS_ROOT}/Manifest.lock", 249 | ); 250 | name = "[CP] Check Pods Manifest.lock"; 251 | outputFileListPaths = ( 252 | ); 253 | outputPaths = ( 254 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | shellPath = /bin/sh; 258 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 259 | showEnvVarsInLog = 0; 260 | }; 261 | 9740EEB61CF901F6004384FC /* Run Script */ = { 262 | isa = PBXShellScriptBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | ); 266 | inputPaths = ( 267 | ); 268 | name = "Run Script"; 269 | outputPaths = ( 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | shellPath = /bin/sh; 273 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 274 | }; 275 | D7B4D54AA176674C5A38B2A1 /* [CP] Embed Pods Frameworks */ = { 276 | isa = PBXShellScriptBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | inputPaths = ( 281 | ); 282 | name = "[CP] Embed Pods Frameworks"; 283 | outputPaths = ( 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | shellPath = /bin/sh; 287 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 288 | showEnvVarsInLog = 0; 289 | }; 290 | /* End PBXShellScriptBuildPhase section */ 291 | 292 | /* Begin PBXSourcesBuildPhase section */ 293 | 97C146EA1CF9000F007C117D /* Sources */ = { 294 | isa = PBXSourcesBuildPhase; 295 | buildActionMask = 2147483647; 296 | files = ( 297 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 298 | 97C146F31CF9000F007C117D /* main.m in Sources */, 299 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 300 | ); 301 | runOnlyForDeploymentPostprocessing = 0; 302 | }; 303 | /* End PBXSourcesBuildPhase section */ 304 | 305 | /* Begin PBXVariantGroup section */ 306 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 307 | isa = PBXVariantGroup; 308 | children = ( 309 | 97C146FB1CF9000F007C117D /* Base */, 310 | ); 311 | name = Main.storyboard; 312 | sourceTree = ""; 313 | }; 314 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 315 | isa = PBXVariantGroup; 316 | children = ( 317 | 97C147001CF9000F007C117D /* Base */, 318 | ); 319 | name = LaunchScreen.storyboard; 320 | sourceTree = ""; 321 | }; 322 | /* End PBXVariantGroup section */ 323 | 324 | /* Begin XCBuildConfiguration section */ 325 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 326 | isa = XCBuildConfiguration; 327 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 328 | buildSettings = { 329 | ALWAYS_SEARCH_USER_PATHS = NO; 330 | CLANG_ANALYZER_NONNULL = YES; 331 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 332 | CLANG_CXX_LIBRARY = "libc++"; 333 | CLANG_ENABLE_MODULES = YES; 334 | CLANG_ENABLE_OBJC_ARC = YES; 335 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 336 | CLANG_WARN_BOOL_CONVERSION = YES; 337 | CLANG_WARN_COMMA = YES; 338 | CLANG_WARN_CONSTANT_CONVERSION = YES; 339 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 340 | CLANG_WARN_EMPTY_BODY = YES; 341 | CLANG_WARN_ENUM_CONVERSION = YES; 342 | CLANG_WARN_INFINITE_RECURSION = YES; 343 | CLANG_WARN_INT_CONVERSION = YES; 344 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 345 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 346 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 347 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 348 | CLANG_WARN_STRICT_PROTOTYPES = YES; 349 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 350 | CLANG_WARN_UNREACHABLE_CODE = YES; 351 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 352 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 353 | COPY_PHASE_STRIP = NO; 354 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 355 | ENABLE_NS_ASSERTIONS = NO; 356 | ENABLE_STRICT_OBJC_MSGSEND = YES; 357 | GCC_C_LANGUAGE_STANDARD = gnu99; 358 | GCC_NO_COMMON_BLOCKS = YES; 359 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 360 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 361 | GCC_WARN_UNDECLARED_SELECTOR = YES; 362 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 363 | GCC_WARN_UNUSED_FUNCTION = YES; 364 | GCC_WARN_UNUSED_VARIABLE = YES; 365 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 366 | MTL_ENABLE_DEBUG_INFO = NO; 367 | SDKROOT = iphoneos; 368 | TARGETED_DEVICE_FAMILY = "1,2"; 369 | VALIDATE_PRODUCT = YES; 370 | }; 371 | name = Profile; 372 | }; 373 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 374 | isa = XCBuildConfiguration; 375 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 376 | buildSettings = { 377 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 378 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 379 | DEVELOPMENT_TEAM = S8QB4VV633; 380 | ENABLE_BITCODE = NO; 381 | FRAMEWORK_SEARCH_PATHS = ( 382 | "$(inherited)", 383 | "$(PROJECT_DIR)/Flutter", 384 | ); 385 | INFOPLIST_FILE = Runner/Info.plist; 386 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 387 | LIBRARY_SEARCH_PATHS = ( 388 | "$(inherited)", 389 | "$(PROJECT_DIR)/Flutter", 390 | ); 391 | PRODUCT_BUNDLE_IDENTIFIER = com.chessluo.flutterStudyApp; 392 | PRODUCT_NAME = "$(TARGET_NAME)"; 393 | VERSIONING_SYSTEM = "apple-generic"; 394 | }; 395 | name = Profile; 396 | }; 397 | 97C147031CF9000F007C117D /* Debug */ = { 398 | isa = XCBuildConfiguration; 399 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 400 | buildSettings = { 401 | ALWAYS_SEARCH_USER_PATHS = NO; 402 | CLANG_ANALYZER_NONNULL = YES; 403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 404 | CLANG_CXX_LIBRARY = "libc++"; 405 | CLANG_ENABLE_MODULES = YES; 406 | CLANG_ENABLE_OBJC_ARC = YES; 407 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 408 | CLANG_WARN_BOOL_CONVERSION = YES; 409 | CLANG_WARN_COMMA = YES; 410 | CLANG_WARN_CONSTANT_CONVERSION = YES; 411 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 412 | CLANG_WARN_EMPTY_BODY = YES; 413 | CLANG_WARN_ENUM_CONVERSION = YES; 414 | CLANG_WARN_INFINITE_RECURSION = YES; 415 | CLANG_WARN_INT_CONVERSION = YES; 416 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 417 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 418 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 419 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 420 | CLANG_WARN_STRICT_PROTOTYPES = YES; 421 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 422 | CLANG_WARN_UNREACHABLE_CODE = YES; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 425 | COPY_PHASE_STRIP = NO; 426 | DEBUG_INFORMATION_FORMAT = dwarf; 427 | ENABLE_STRICT_OBJC_MSGSEND = YES; 428 | ENABLE_TESTABILITY = YES; 429 | GCC_C_LANGUAGE_STANDARD = gnu99; 430 | GCC_DYNAMIC_NO_PIC = NO; 431 | GCC_NO_COMMON_BLOCKS = YES; 432 | GCC_OPTIMIZATION_LEVEL = 0; 433 | GCC_PREPROCESSOR_DEFINITIONS = ( 434 | "DEBUG=1", 435 | "$(inherited)", 436 | ); 437 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 438 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 439 | GCC_WARN_UNDECLARED_SELECTOR = YES; 440 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 441 | GCC_WARN_UNUSED_FUNCTION = YES; 442 | GCC_WARN_UNUSED_VARIABLE = YES; 443 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 444 | MTL_ENABLE_DEBUG_INFO = YES; 445 | ONLY_ACTIVE_ARCH = YES; 446 | SDKROOT = iphoneos; 447 | TARGETED_DEVICE_FAMILY = "1,2"; 448 | }; 449 | name = Debug; 450 | }; 451 | 97C147041CF9000F007C117D /* Release */ = { 452 | isa = XCBuildConfiguration; 453 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 454 | buildSettings = { 455 | ALWAYS_SEARCH_USER_PATHS = NO; 456 | CLANG_ANALYZER_NONNULL = YES; 457 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 458 | CLANG_CXX_LIBRARY = "libc++"; 459 | CLANG_ENABLE_MODULES = YES; 460 | CLANG_ENABLE_OBJC_ARC = YES; 461 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 462 | CLANG_WARN_BOOL_CONVERSION = YES; 463 | CLANG_WARN_COMMA = YES; 464 | CLANG_WARN_CONSTANT_CONVERSION = YES; 465 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 466 | CLANG_WARN_EMPTY_BODY = YES; 467 | CLANG_WARN_ENUM_CONVERSION = YES; 468 | CLANG_WARN_INFINITE_RECURSION = YES; 469 | CLANG_WARN_INT_CONVERSION = YES; 470 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 471 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 472 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 473 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 474 | CLANG_WARN_STRICT_PROTOTYPES = YES; 475 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 476 | CLANG_WARN_UNREACHABLE_CODE = YES; 477 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 478 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 479 | COPY_PHASE_STRIP = NO; 480 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 481 | ENABLE_NS_ASSERTIONS = NO; 482 | ENABLE_STRICT_OBJC_MSGSEND = YES; 483 | GCC_C_LANGUAGE_STANDARD = gnu99; 484 | GCC_NO_COMMON_BLOCKS = YES; 485 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 486 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 487 | GCC_WARN_UNDECLARED_SELECTOR = YES; 488 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 489 | GCC_WARN_UNUSED_FUNCTION = YES; 490 | GCC_WARN_UNUSED_VARIABLE = YES; 491 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 492 | MTL_ENABLE_DEBUG_INFO = NO; 493 | SDKROOT = iphoneos; 494 | TARGETED_DEVICE_FAMILY = "1,2"; 495 | VALIDATE_PRODUCT = YES; 496 | }; 497 | name = Release; 498 | }; 499 | 97C147061CF9000F007C117D /* Debug */ = { 500 | isa = XCBuildConfiguration; 501 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 502 | buildSettings = { 503 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 504 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 505 | ENABLE_BITCODE = NO; 506 | FRAMEWORK_SEARCH_PATHS = ( 507 | "$(inherited)", 508 | "$(PROJECT_DIR)/Flutter", 509 | ); 510 | INFOPLIST_FILE = Runner/Info.plist; 511 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 512 | LIBRARY_SEARCH_PATHS = ( 513 | "$(inherited)", 514 | "$(PROJECT_DIR)/Flutter", 515 | ); 516 | PRODUCT_BUNDLE_IDENTIFIER = com.chessluo.flutterStudyApp; 517 | PRODUCT_NAME = "$(TARGET_NAME)"; 518 | VERSIONING_SYSTEM = "apple-generic"; 519 | }; 520 | name = Debug; 521 | }; 522 | 97C147071CF9000F007C117D /* Release */ = { 523 | isa = XCBuildConfiguration; 524 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 525 | buildSettings = { 526 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 527 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 528 | ENABLE_BITCODE = NO; 529 | FRAMEWORK_SEARCH_PATHS = ( 530 | "$(inherited)", 531 | "$(PROJECT_DIR)/Flutter", 532 | ); 533 | INFOPLIST_FILE = Runner/Info.plist; 534 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 535 | LIBRARY_SEARCH_PATHS = ( 536 | "$(inherited)", 537 | "$(PROJECT_DIR)/Flutter", 538 | ); 539 | PRODUCT_BUNDLE_IDENTIFIER = com.chessluo.flutterStudyApp; 540 | PRODUCT_NAME = "$(TARGET_NAME)"; 541 | VERSIONING_SYSTEM = "apple-generic"; 542 | }; 543 | name = Release; 544 | }; 545 | /* End XCBuildConfiguration section */ 546 | 547 | /* Begin XCConfigurationList section */ 548 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 549 | isa = XCConfigurationList; 550 | buildConfigurations = ( 551 | 97C147031CF9000F007C117D /* Debug */, 552 | 97C147041CF9000F007C117D /* Release */, 553 | 249021D3217E4FDB00AE95B9 /* Profile */, 554 | ); 555 | defaultConfigurationIsVisible = 0; 556 | defaultConfigurationName = Release; 557 | }; 558 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 559 | isa = XCConfigurationList; 560 | buildConfigurations = ( 561 | 97C147061CF9000F007C117D /* Debug */, 562 | 97C147071CF9000F007C117D /* Release */, 563 | 249021D4217E4FDB00AE95B9 /* Profile */, 564 | ); 565 | defaultConfigurationIsVisible = 0; 566 | defaultConfigurationName = Release; 567 | }; 568 | /* End XCConfigurationList section */ 569 | }; 570 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 571 | } 572 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; 9 | 10 | FlutterMethodChannel* batteryChannel = [FlutterMethodChannel 11 | methodChannelWithName:@"flutter_study_app" 12 | binaryMessenger:controller]; 13 | 14 | [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { 15 | // TODO 16 | if ([@"getBatteryLevel" isEqualToString:call.method]) { 17 | int batteryLevel = [self getBatteryLevel]; 18 | 19 | if (batteryLevel == -1) { 20 | result([FlutterError errorWithCode:@"UNAVAILABLE" 21 | message:@"Battery info unavailable" 22 | details:nil]); 23 | } else { 24 | result(@(batteryLevel)); 25 | } 26 | } else { 27 | result(FlutterMethodNotImplemented); 28 | } 29 | }]; 30 | 31 | // Override point for customization after application launch. 32 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 33 | } 34 | 35 | - (int)getBatteryLevel { 36 | UIDevice* device = UIDevice.currentDevice; 37 | device.batteryMonitoringEnabled = YES; 38 | if (device.batteryState == UIDeviceBatteryStateUnknown) { 39 | return -1; 40 | } else { 41 | return (int)(device.batteryLevel * 100); 42 | } 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_study_app 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 | -------------------------------------------------------------------------------- /ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/common/constant.dart: -------------------------------------------------------------------------------- 1 | 2 | class Constant { 3 | // static const String SQFLITE_ROUTE = "SqfliteRoute"; 4 | // static const String EVENTBUS_ROUTE = "EventBusRoute"; 5 | // static const String FILE_ZIP_ROUTE = "FileZipRoute"; 6 | // static const String PROVIDER_ROUTE = "ProviderRoute"; 7 | // 8 | // static const String HOME_PAGE = "HomePage"; 9 | 10 | } -------------------------------------------------------------------------------- /lib/common/events.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an example of how to set up the [EventBus] and its events. 3 | */ 4 | import 'package:event_bus/event_bus.dart'; 5 | 6 | /// The global [EventBus] object. 7 | EventBus eventBus = EventBus(); 8 | 9 | /// Event 修改主题色 10 | class ThemeColorEvent { 11 | String colorStr; 12 | 13 | ThemeColorEvent(this.colorStr); 14 | } -------------------------------------------------------------------------------- /lib/common/model/func_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FuncModel { 4 | String name; 5 | Color bgColor; 6 | String routePath; 7 | Object arguments; 8 | int index; 9 | 10 | FuncModel({this.name,this.bgColor, this.routePath, this.arguments, this.index}); 11 | } 12 | -------------------------------------------------------------------------------- /lib/fl_app.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:fluro/fluro.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_study_app/pages/transition_page.dart'; 6 | import 'package:flutter_study_app/provider/color_filtered_model.dart'; 7 | import 'package:flutter_study_app/res/colors.dart'; 8 | import 'package:flutter_study_app/routers/application.dart'; 9 | import 'package:flutter_study_app/routers/routers.dart'; 10 | import 'package:flutter_study_app/utils/object_util.dart'; 11 | import 'package:provider/provider.dart'; 12 | import 'package:shared_preferences/shared_preferences.dart'; 13 | 14 | import 'common/events.dart'; 15 | 16 | class MyApp extends StatefulWidget { 17 | MyApp() { 18 | final router = new FluroRouter(); 19 | Routes.configureRoutes(router); 20 | Application.router = router; 21 | } 22 | 23 | @override 24 | State createState() { 25 | return _MyAppState(); 26 | } 27 | } 28 | 29 | class _MyAppState extends State { 30 | Color _primaryColor; 31 | StreamSubscription _colorSubscription; 32 | 33 | @override 34 | void dispose() { 35 | super.dispose(); 36 | //取消订阅 37 | _colorSubscription.cancel(); 38 | } 39 | 40 | @override 41 | void initState() { 42 | super.initState(); 43 | _setThemeColor(); 44 | //订阅eventbus 45 | _colorSubscription = eventBus.on().listen((event) { 46 | try { 47 | Color color = AppColors.getColor(event.colorStr); 48 | setState(() { 49 | _primaryColor = color; 50 | }); 51 | //缓存主题色 52 | _cacheColor(event.colorStr); 53 | } catch (e) {} 54 | }); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | return Consumer( 60 | builder: (BuildContext context, colorFiltered, Widget child) { 61 | return ColorFiltered( 62 | colorFilter: 63 | ColorFilter.mode(colorFiltered.currentColor, BlendMode.color), 64 | child: MaterialApp( 65 | debugShowCheckedModeBanner: false, 66 | title: 'Flutter Demo', 67 | theme: ThemeData( 68 | primaryColor: _primaryColor, 69 | //跟随iOS风格的主题 70 | platform: TargetPlatform.iOS, 71 | splashColor: Colors.transparent), 72 | home: TransitionPage(), 73 | onGenerateRoute: Application.router.generator, 74 | ), 75 | ); 76 | }, 77 | ); 78 | } 79 | 80 | _cacheColor(String colorStr) async { 81 | SharedPreferences sp = await SharedPreferences.getInstance(); 82 | sp.setString("themeColorStr", colorStr); 83 | } 84 | 85 | Future _getCacheColor(String colorKey) async { 86 | SharedPreferences sp = await SharedPreferences.getInstance(); 87 | String colorStr = sp.getString(colorKey); 88 | return colorStr; 89 | } 90 | 91 | void _setThemeColor() async { 92 | String cacheColorStr = await _getCacheColor("themeColorStr"); 93 | if (ObjectUtil.isNotEmpty(cacheColorStr)) { 94 | setState(() { 95 | _primaryColor = AppColors.getColor(cacheColorStr); 96 | }); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_study_app/provider/color_filtered_model.dart'; 6 | import 'package:provider/provider.dart'; 7 | 8 | import 'fl_app.dart'; 9 | 10 | void main() { 11 | runApp(MultiProvider( 12 | providers: [ 13 | ChangeNotifierProvider.value(value: ColorFilteredProvider()), 14 | ], 15 | child: MyApp(), 16 | )); 17 | 18 | if (Platform.isAndroid) { 19 | ///设置状态栏透明 20 | SystemUiOverlayStyle systemUiOverlayStyle = 21 | SystemUiOverlayStyle(statusBarColor: Colors.transparent); 22 | SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/pages/anim/anim_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 flutter Canvas与动画相关demo 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2020-04-04 6 | * 7 | */ 8 | import 'package:fluro/fluro.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_study_app/common/model/func_model.dart'; 11 | import 'package:flutter_study_app/routers/application.dart'; 12 | import 'package:flutter_study_app/routers/routers.dart'; 13 | 14 | class AnimDemoList extends StatefulWidget { 15 | @override 16 | State createState() { 17 | return _ListViewState(); 18 | } 19 | } 20 | 21 | class _ListViewState extends State { 22 | List itemTitles = [ 23 | FuncModel(name: 'CustomPaint', routePath: Routes.customPaintPage), 24 | ]; 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Scaffold( 29 | appBar: AppBar( 30 | centerTitle: true, 31 | title: Text("Canvas与动画"), 32 | ), 33 | body: ListView.builder( 34 | itemCount: itemTitles.length, 35 | itemBuilder: (BuildContext context, int index) { 36 | return _listItem(itemTitles[index].name, () { 37 | Application.router.navigateTo( 38 | context, itemTitles[index].routePath, 39 | transition: TransitionType.inFromRight); 40 | }); 41 | }), 42 | ); 43 | } 44 | 45 | ///demo Item入口View 46 | Widget _listItem(String itemTitle, Function onTap) { 47 | return Container( 48 | decoration: BoxDecoration( 49 | color: Colors.white, 50 | border: BorderDirectional(bottom: BorderSide(color: Colors.grey))), 51 | child: ListTile( 52 | title: Text(itemTitle), 53 | trailing: Icon(Icons.keyboard_arrow_right), 54 | onTap: onTap, 55 | ), 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/pages/anim/basis_canvas_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'dart:ui' as ui; 5 | 6 | class CustomPaintPage extends StatefulWidget { 7 | const CustomPaintPage({Key key}) : super(key: key); 8 | 9 | @override 10 | _CustomPaintPageState createState() => _CustomPaintPageState(); 11 | } 12 | 13 | 14 | class _CustomPaintPageState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return Scaffold( 18 | appBar: AppBar( 19 | title: Text("绘图"), 20 | ), 21 | body: Container( 22 | child: Container( 23 | // color: Colors.amberAccent, 24 | width: MediaQuery.of(context).size.width, 25 | height: MediaQuery.of(context).size.height, 26 | child: RepaintBoundary( 27 | child: CustomPaint( 28 | //使用CustomPaint盛放画布 29 | painter: BasisCustomPainter(), 30 | ), 31 | ), 32 | ), 33 | )); 34 | } 35 | } 36 | 37 | class BasisCustomPainter extends CustomPainter { 38 | Paint _paint; 39 | Paint _linePaint; 40 | Paint _pathPaint; 41 | var _radius = 30.0; //小球半径 42 | Path _path = Path(); //画笔对象 43 | BasisCustomPainter() { 44 | _paint = Paint() 45 | ..color = Colors.red 46 | ..style = PaintingStyle.stroke 47 | ..strokeWidth = 10; 48 | 49 | _pathPaint = Paint() 50 | ..color = Colors.black 51 | ..style = PaintingStyle 52 | .fill //Paint.style,还可以设置为PaintingStyle.fill,填充了,PaintingStyle.stroke 53 | ..strokeWidth = 5; 54 | } 55 | 56 | //// 绘制自定义的效果 57 | ///paint通过canvas绘制,size为当前控件的大小 58 | @override 59 | void paint(Canvas canvas, Size size) { 60 | //PointMode有3种模式: 61 | //points:点 62 | //lines:将2个点绘制为线段,如果点的个数为奇数,最后一个点将会被忽略 63 | //polygon:将整个点绘制为一条线 64 | 65 | //点,Offset为坐标向量 66 | List points = [ 67 | Offset(10, 100), 68 | Offset(size.width / 2 - 50, size.height / 2 + 50), 69 | Offset(size.width - 100, size.height - 80), 70 | ]; 71 | 72 | canvas.drawPoints(PointMode.points, points, _paint); 73 | //线 74 | canvas.drawLine(Offset(0, 0), Offset(size.width, size.height), _paint); 75 | 76 | var _path = Path() 77 | ..moveTo(0, 0) 78 | ..lineTo(size.width, 0) 79 | ..lineTo(size.width, size.height) 80 | ..close(); 81 | //裁剪由线围成区域 82 | // canvas.clipPath(_path); 83 | //绘制路径 84 | canvas.drawPath(_path, _pathPaint); 85 | //绘制圆形 86 | canvas.drawCircle(Offset(size.width / 2, size.height / 2), _radius, _paint); 87 | //绘制椭圆 88 | canvas.drawOval(Rect.fromLTRB(0, 0, size.width, size.height / 2), _paint); 89 | //文字 90 | ParagraphBuilder pb = ParagraphBuilder(ParagraphStyle( 91 | textAlign: TextAlign.center, 92 | fontWeight: FontWeight.w600, 93 | fontStyle: FontStyle.normal, 94 | fontSize: 18, 95 | )) 96 | // ..pushStyle(TextStyle(color: Colors.black)) 97 | ..pushStyle(ui.TextStyle(color: Colors.amberAccent)) 98 | ..addText( 99 | 'Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。'); 100 | ParagraphConstraints pc = ParagraphConstraints(width: size.width - 60); 101 | Paragraph paragraph = pb.build()..layout(pc); 102 | canvas.drawParagraph(paragraph, Offset(30, 30)); 103 | //绘制阴影 104 | //drawShadow 用于绘制阴影,第一个参数为绘制一个图形 Path,第二个设置阴影颜色, 105 | //第三个为阴影范围,最后一个阴影范围是否填充满 106 | canvas.drawShadow(_path, Colors.blue, 3, false); 107 | //绘制图片 108 | // canvas.drawImage(image, offset, paint); 109 | // canvas.drawImageRect(image, src, dst, paint); 110 | // canvas.drawImageNine(image, center, dst, paint); 111 | //绘制圆角矩形 112 | canvas.drawRRect( 113 | RRect.fromLTRBR(10, 10, 200, 200, Radius.circular(10)), _paint); 114 | //裁剪矩形 115 | //clipRect 可以在规定的矩形内进行绘制,超出范围不绘制 116 | // canvas.clipRect(Rect.fromLTWH(30, 100, size.width / 0.3 - 60, 300), 117 | // doAntiAlias: false); 118 | } 119 | 120 | @override 121 | bool shouldRepaint(covariant CustomPainter oldDelegate) { 122 | //当前实例和旧实例属性是否一致 123 | return false; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /lib/pages/cache/demo/preferences_demo.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 shared_preferences数据持久化 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019/7/29 6 | * 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:fluttertoast/fluttertoast.dart'; 11 | import 'package:shared_preferences/shared_preferences.dart'; 12 | 13 | 14 | class PreferencesDemo extends StatefulWidget{ 15 | 16 | @override 17 | State createState() { 18 | // TODO: implement createState 19 | return _PreferencesState(); 20 | } 21 | 22 | } 23 | 24 | class _PreferencesState extends State { 25 | 26 | TextEditingController _nameController=new TextEditingController(); 27 | TextEditingController _ageController=new TextEditingController(); 28 | String _data = "暂无数据"; 29 | 30 | String userNameKey = "sp_user_name_key"; 31 | String userAgeKey = "sp_user_age_key"; 32 | 33 | 34 | @override 35 | void initState() { 36 | super.initState(); 37 | 38 | } 39 | 40 | 41 | ///增 42 | _add() async { 43 | SharedPreferences prefs = await SharedPreferences.getInstance(); 44 | prefs.setString(userNameKey, '${_nameController.text}'); 45 | prefs.setString(userAgeKey, '${_ageController.text}'); 46 | 47 | setState(() { 48 | _data = "插入用户名和年龄数据成功!"; 49 | }); 50 | } 51 | 52 | 53 | ///删 54 | _delete() async { 55 | SharedPreferences prefs = await SharedPreferences.getInstance(); 56 | 57 | String username = prefs.get(userNameKey); 58 | String age = prefs.get(userAgeKey); 59 | if(username==null||age==null){ 60 | setState(() { 61 | _data = '数据为空,暂无法执行删除'; 62 | }); 63 | }else{ 64 | //KEY 65 | prefs.remove(userNameKey); 66 | prefs.remove(userAgeKey); 67 | //清空所有KEY 68 | //prefs.clear(); 69 | 70 | setState(() { 71 | _data = '_delete 用户名和年龄值 成功'; 72 | }); 73 | } 74 | 75 | } 76 | 77 | ///改 78 | _update() async { 79 | SharedPreferences prefs = await SharedPreferences.getInstance(); 80 | prefs.setString(userNameKey, '${_nameController.text}'); 81 | prefs.setString(userAgeKey, '${_ageController.text}'); 82 | 83 | setState(() { 84 | _data = "修改数据成功!"; 85 | }); 86 | } 87 | 88 | 89 | ///查全部 90 | _query() async { 91 | SharedPreferences prefs = await SharedPreferences.getInstance(); 92 | String username = prefs.get(userNameKey); 93 | String age = prefs.get(userAgeKey); 94 | 95 | print('$username'); 96 | print('$age'); 97 | 98 | setState(() { 99 | _data = '_query 成功: username: $username age: $age'; 100 | }); 101 | } 102 | 103 | 104 | @override 105 | Widget build(BuildContext context) { 106 | // TODO: implement build 107 | return Scaffold( 108 | appBar: AppBar( 109 | centerTitle: true, 110 | iconTheme: IconThemeData(color: Colors.white), 111 | title: Text("shared_preferences",style: TextStyle(color: Colors.white),), 112 | ), 113 | body: Container( 114 | margin: EdgeInsets.only(left: 20,right: 20,top: 20), 115 | child: ListView( 116 | children: [ 117 | Center( 118 | child: Text("设置进入程序默认用户名和年龄数据为空,如下将可以key-value形式对用户名和年龄进行增删改查操作", 119 | style: TextStyle(fontSize: 14,color: Color(0xff666666)),), 120 | ), 121 | Padding(padding: EdgeInsets.only(top: 10)), 122 | _getNameInputView(), 123 | Padding(padding: EdgeInsets.only(top: 10)), 124 | _getAgeInputView(), 125 | Padding(padding: EdgeInsets.only(top: 30)), 126 | _getAddBtnView(), 127 | Padding(padding: EdgeInsets.only(top: 10)), 128 | _getdeleteBtnView(), 129 | Padding(padding: EdgeInsets.only(top: 10)), 130 | _getUpdateBtnView(), 131 | Padding(padding: EdgeInsets.only(top: 10)), 132 | _getQueryBtnView(), 133 | Padding(padding: EdgeInsets.only(top: 30)), 134 | Text(_data,style: TextStyle(color: Colors.red,fontSize: 18),) 135 | ], 136 | ), 137 | ), 138 | resizeToAvoidBottomInset: false, 139 | ); 140 | } 141 | 142 | 143 | _getNameInputView() { 144 | return TextField( 145 | keyboardType: TextInputType.text, 146 | style: TextStyle(color: Color(0xFF888888)), 147 | controller: _nameController, 148 | decoration: InputDecoration( 149 | hintText: "姓名", 150 | hintStyle: TextStyle(color: Color(0xFF888888)), 151 | contentPadding: EdgeInsets.only(left: 10,right: 10,bottom: 10,top: 10), 152 | border: OutlineInputBorder( 153 | borderRadius: BorderRadius.circular(8.0), 154 | ), 155 | ), 156 | ); 157 | } 158 | 159 | _getAgeInputView() { 160 | return TextField( 161 | keyboardType: TextInputType.text, 162 | style: TextStyle(color: Color(0xFF888888)), 163 | controller: _ageController, 164 | decoration: InputDecoration( 165 | hintText: "年龄", 166 | hintStyle: TextStyle(color: Color(0xFF888888)), 167 | contentPadding: EdgeInsets.only(left: 10,right: 10,bottom: 10,top: 10), 168 | border: OutlineInputBorder( 169 | borderRadius: BorderRadius.circular(8.0), 170 | ), 171 | ), 172 | ); 173 | } 174 | 175 | _getAddBtnView(){ 176 | return RaisedButton( 177 | onPressed: (){ 178 | if(_nameController.text==null||_nameController.text==""){ 179 | Fluttertoast.showToast(msg: "插入数据不能为空!",backgroundColor: Colors.orange); 180 | return; 181 | } 182 | if(_ageController.text==null||_ageController.text==""){ 183 | Fluttertoast.showToast(msg: "插入数据不能为空!",backgroundColor: Colors.orange); 184 | return; 185 | } 186 | _add(); 187 | 188 | }, 189 | child: Text("插入数据",style: TextStyle(color: Colors.white,fontSize: 18),), 190 | color: Colors.orange, 191 | shape: RoundedRectangleBorder( 192 | borderRadius: BorderRadius.circular(5), 193 | ) 194 | ); 195 | } 196 | 197 | _getdeleteBtnView(){ 198 | return RaisedButton( 199 | onPressed: (){ 200 | 201 | _delete(); 202 | }, 203 | child: Text("删除数据",style: TextStyle(color: Colors.white,fontSize: 18),), 204 | color: Colors.orange, 205 | shape: RoundedRectangleBorder( 206 | borderRadius: BorderRadius.circular(5), 207 | ) 208 | ); 209 | } 210 | 211 | _getUpdateBtnView(){ 212 | return RaisedButton( 213 | onPressed: (){ 214 | if(_nameController.text==null||_nameController.text==""){ 215 | Fluttertoast.showToast(msg: "姓名不能为空!",backgroundColor: Colors.orange); 216 | return; 217 | } 218 | 219 | _update(); 220 | }, 221 | child: Text("修改姓名数据",style: TextStyle(color: Colors.white,fontSize: 18),), 222 | color: Colors.orange, 223 | shape: RoundedRectangleBorder( 224 | borderRadius: BorderRadius.circular(5), 225 | ) 226 | ); 227 | } 228 | 229 | _getQueryBtnView(){ 230 | return RaisedButton( 231 | onPressed: (){ 232 | _query(); 233 | }, 234 | child: Text("查询数据",style: TextStyle(color: Colors.white,fontSize: 18),), 235 | color: Colors.orange, 236 | shape: RoundedRectangleBorder( 237 | borderRadius: BorderRadius.circular(5), 238 | ) 239 | ); 240 | } 241 | 242 | } -------------------------------------------------------------------------------- /lib/pages/cache/demo/sqflite_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttertoast/fluttertoast.dart'; 3 | import 'package:path/path.dart'; 4 | import 'package:sqflite/sqflite.dart'; 5 | 6 | class SqflitePage extends StatefulWidget { 7 | @override 8 | State createState() { 9 | // TODO: implement createState 10 | return _SqflitePageState(); 11 | } 12 | } 13 | 14 | class _SqflitePageState extends State { 15 | TextEditingController _nameController = new TextEditingController(); 16 | TextEditingController _ageController = new TextEditingController(); 17 | String _data = "暂无数据"; 18 | String _dbName = 'user.db'; //数据库名称 19 | 20 | String _createTableSQL = 21 | 'CREATE TABLE student_table (id INTEGER PRIMARY KEY, name TEXT,age INTEGER)'; //创建学生表; 22 | int _dbVersion = 1; //数据库版本 23 | 24 | @override 25 | void initState() { 26 | super.initState(); 27 | //创建数据库、学生表 28 | _createDb(_dbName, _dbVersion, _createTableSQL); 29 | } 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | // TODO: implement build 34 | return Scaffold( 35 | appBar: AppBar( 36 | centerTitle: true, 37 | iconTheme: IconThemeData(color: Colors.white), 38 | title: Text( 39 | "sqflite数据存储", 40 | style: TextStyle(color: Colors.white), 41 | ), 42 | ), 43 | body: Container( 44 | margin: EdgeInsets.only(left: 20, right: 20, top: 20), 45 | child: ListView( 46 | children: [ 47 | Center( 48 | child: Text( 49 | "设置进入程序默认创建数据库和一张学生表,如下可对表的姓名、年龄进行增删改查操作:", 50 | style: TextStyle(fontSize: 14, color: Color(0xff666666)), 51 | ), 52 | ), 53 | Padding(padding: EdgeInsets.only(top: 10)), 54 | _getNameInputView(), 55 | Padding(padding: EdgeInsets.only(top: 10)), 56 | _getAgeInputView(), 57 | Padding(padding: EdgeInsets.only(top: 30)), 58 | _getAddBtnView(), 59 | Padding(padding: EdgeInsets.only(top: 10)), 60 | _getdeleteBtnView(), 61 | Padding(padding: EdgeInsets.only(top: 10)), 62 | _getUpdateBtnView(), 63 | Padding(padding: EdgeInsets.only(top: 10)), 64 | _getQueryBtnView(), 65 | Padding(padding: EdgeInsets.only(top: 30)), 66 | Text( 67 | _data, 68 | style: TextStyle(color: Colors.red, fontSize: 18), 69 | ) 70 | ], 71 | ), 72 | ), 73 | resizeToAvoidBottomInset: false, 74 | ); 75 | } 76 | 77 | _getNameInputView() { 78 | return TextField( 79 | keyboardType: TextInputType.text, 80 | style: TextStyle(color: Color(0xFF888888)), 81 | controller: _nameController, 82 | decoration: InputDecoration( 83 | hintText: "姓名", 84 | hintStyle: TextStyle(color: Color(0xFF888888)), 85 | contentPadding: 86 | EdgeInsets.only(left: 10, right: 10, bottom: 10, top: 10), 87 | border: OutlineInputBorder( 88 | borderRadius: BorderRadius.circular(8.0), 89 | ), 90 | ), 91 | ); 92 | } 93 | 94 | _getAgeInputView() { 95 | return TextField( 96 | keyboardType: TextInputType.text, 97 | style: TextStyle(color: Color(0xFF888888)), 98 | controller: _ageController, 99 | decoration: InputDecoration( 100 | hintText: "年龄", 101 | hintStyle: TextStyle(color: Color(0xFF888888)), 102 | contentPadding: 103 | EdgeInsets.only(left: 10, right: 10, bottom: 10, top: 10), 104 | border: OutlineInputBorder( 105 | borderRadius: BorderRadius.circular(8.0), 106 | ), 107 | ), 108 | ); 109 | } 110 | 111 | _getAddBtnView() { 112 | return RaisedButton( 113 | onPressed: () { 114 | if (_nameController.text == null || _nameController.text == "") { 115 | Fluttertoast.showToast( 116 | msg: "插入数据不能为空!", backgroundColor: Colors.orange); 117 | return; 118 | } 119 | if (_ageController.text == null || _ageController.text == "") { 120 | Fluttertoast.showToast( 121 | msg: "插入数据不能为空!", backgroundColor: Colors.orange); 122 | return; 123 | } 124 | String sql = 125 | "INSERT INTO student_table(name,age) VALUES('${_nameController.text}','${_ageController.text}')"; 126 | _add(_dbName, sql); 127 | }, 128 | child: Text( 129 | "插入数据", 130 | style: TextStyle(color: Colors.white, fontSize: 18), 131 | ), 132 | color: Colors.orange, 133 | shape: RoundedRectangleBorder( 134 | borderRadius: BorderRadius.circular(5), 135 | )); 136 | } 137 | 138 | _getdeleteBtnView() { 139 | return RaisedButton( 140 | onPressed: () { 141 | String sql = "DELETE FROM student_table"; //无条件删除学生表数据 142 | _delete(_dbName, sql); 143 | }, 144 | child: Text( 145 | "删除数据", 146 | style: TextStyle(color: Colors.white, fontSize: 18), 147 | ), 148 | color: Colors.orange, 149 | shape: RoundedRectangleBorder( 150 | borderRadius: BorderRadius.circular(5), 151 | )); 152 | } 153 | 154 | _getUpdateBtnView() { 155 | return RaisedButton( 156 | onPressed: () { 157 | if (_nameController.text == null || _nameController.text == "") { 158 | Fluttertoast.showToast( 159 | msg: "姓名不能为空!", backgroundColor: Colors.orange); 160 | return; 161 | } 162 | 163 | String sql = "UPDATE student_table SET name =? WHERE id = ?"; 164 | _update(_dbName, sql, [_nameController.text, 1]); 165 | }, 166 | child: Text( 167 | "修改姓名数据", 168 | style: TextStyle(color: Colors.white, fontSize: 18), 169 | ), 170 | color: Colors.orange, 171 | shape: RoundedRectangleBorder( 172 | borderRadius: BorderRadius.circular(5), 173 | )); 174 | } 175 | 176 | _getQueryBtnView() { 177 | return RaisedButton( 178 | onPressed: () { 179 | String sql = 'SELECT * FROM student_table'; 180 | _query(_dbName, sql); 181 | }, 182 | child: Text( 183 | "查询数据", 184 | style: TextStyle(color: Colors.white, fontSize: 18), 185 | ), 186 | color: Colors.orange, 187 | shape: RoundedRectangleBorder( 188 | borderRadius: BorderRadius.circular(5), 189 | )); 190 | } 191 | 192 | ///创建数据库db 193 | _createDb(String dbName, int vers, String dbTables) async { 194 | //获取数据库路径 195 | var databasesPath = await getDatabasesPath(); 196 | String path = join(databasesPath, dbName); 197 | print("数据库路径:$path数据库版本$vers"); 198 | //打开数据库 199 | await openDatabase(path, version: vers, 200 | onUpgrade: (Database db, int oldVersion, int newVersion) async { 201 | //数据库升级,只回调一次 202 | print("数据库需要升级!旧版:$oldVersion,新版:$newVersion"); 203 | }, onCreate: (Database db, int vers) async { 204 | //创建表,只回调一次 205 | await db.execute(dbTables); 206 | await db.close(); 207 | }); 208 | 209 | setState(() { 210 | _data = "成功创建数据库db!\n数据库路径: $path \n数据库版本$vers"; 211 | }); 212 | } 213 | 214 | ///增 215 | _add(String dbName, String sql) async { 216 | //获取数据库路径 217 | var databasesPath = await getDatabasesPath(); 218 | String path = join(databasesPath, dbName); 219 | print("数据库路径:$path"); 220 | 221 | Database db = await openDatabase(path); 222 | await db.transaction((txn) async { 223 | int count = await txn.rawInsert(sql); 224 | }); 225 | await db.close(); 226 | 227 | setState(() { 228 | _data = "插入数据成功!"; 229 | }); 230 | } 231 | 232 | ///删 233 | _delete(String dbName, String sql) async { 234 | var databasesPath = await getDatabasesPath(); 235 | String path = join(databasesPath, dbName); 236 | 237 | Database db = await openDatabase(path); 238 | int count = await db.rawDelete(sql); 239 | await db.close(); 240 | 241 | if (count > 0) { 242 | setState(() { 243 | _data = "执行删除操作完成,该sql删除条件下的数目为:$count"; 244 | }); 245 | } else { 246 | setState(() { 247 | _data = "无法执行删除操作,该sql删除条件下的数目为:$count"; 248 | }); 249 | } 250 | } 251 | 252 | ///改 253 | _update(String dbName, String sql, List arg) async { 254 | var databasesPath = await getDatabasesPath(); 255 | String path = join(databasesPath, dbName); 256 | 257 | Database db = await openDatabase(path); 258 | int count = await db.rawUpdate(sql, arg); //修改条件,对应参数值 259 | await db.close(); 260 | if (count > 0) { 261 | setState(() { 262 | _data = "更新数据库操作完成,该sql删除条件下的数目为:$count"; 263 | }); 264 | } else { 265 | setState(() { 266 | _data = "无法更新数据库,该sql删除条件下的数目为:$count"; 267 | }); 268 | } 269 | } 270 | 271 | ///查条数 272 | _getQueryNum(String dbName, String sql) async { 273 | var databasesPath = await getDatabasesPath(); 274 | String path = join(databasesPath, dbName); 275 | 276 | Database db = await openDatabase(path); 277 | int count = Sqflite.firstIntValue(await db.rawQuery(sql)); 278 | await db.close(); 279 | return count; 280 | } 281 | 282 | ///查全部 283 | _query(String dbName, String sql) async { 284 | var databasesPath = await getDatabasesPath(); 285 | String path = join(databasesPath, dbName); 286 | 287 | Database db = await openDatabase(path); 288 | List list = await db.rawQuery(sql); 289 | await db.close(); 290 | setState(() { 291 | _data = "数据详情:$list"; 292 | }); 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /lib/pages/cache/local_cache_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 数据库存储相关demo 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019-11-03 6 | * 7 | */ 8 | /// 9 | import 'package:fluro/fluro.dart'; 10 | import 'package:flutter/material.dart'; 11 | import 'package:flutter_study_app/common/model/func_model.dart'; 12 | import 'package:flutter_study_app/routers/application.dart'; 13 | import 'package:flutter_study_app/routers/routers.dart'; 14 | 15 | class LocalCachePage extends StatefulWidget { 16 | @override 17 | State createState() { 18 | return _ListViewState(); 19 | } 20 | } 21 | 22 | class _ListViewState extends State { 23 | List itemTitles = [ 24 | FuncModel(name: 'sqflite数据库', routePath: Routes.sqflitePage), 25 | FuncModel( 26 | name: 'shared_preferences数据持久化', routePath: Routes.sharedPreferences) 27 | ]; 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return Scaffold( 32 | appBar: AppBar( 33 | centerTitle: true, 34 | title: Text("本地数据存储"), 35 | ), 36 | body: ListView.builder( 37 | itemCount: itemTitles.length, 38 | itemBuilder: (BuildContext context, int index) { 39 | return _listItem(itemTitles[index].name, () { 40 | Application.router.navigateTo( 41 | context, itemTitles[index].routePath, 42 | transition: TransitionType.inFromRight); 43 | }); 44 | }), 45 | ); 46 | } 47 | 48 | ///demo Item入口View 49 | Widget _listItem(String itemTitle, Function onTap) { 50 | return Container( 51 | decoration: BoxDecoration( 52 | color: Colors.white, 53 | border: BorderDirectional(bottom: BorderSide(color: Colors.grey))), 54 | child: ListTile( 55 | title: Text(itemTitle), 56 | trailing: Icon(Icons.keyboard_arrow_right), 57 | onTap: onTap, 58 | ), 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/pages/channel/flutter_channel_demo.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 flultter channel与原生交互通道 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @github https://github.com/ChessLuo 6 | * @date 2019-08-10 7 | * 8 | */ 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter/services.dart'; 11 | 12 | class ChannelDemo extends StatefulWidget { 13 | @override 14 | State createState() { 15 | // TODO: implement createState 16 | return ChannelState(); 17 | } 18 | } 19 | 20 | class ChannelState extends State { 21 | static const platform = const MethodChannel('flutter_study_app'); 22 | String _batteryLevel = '电池电量未知'; 23 | 24 | @override 25 | void initState() { 26 | // TODO: implement initState 27 | super.initState(); 28 | } 29 | 30 | ///获取电池电量的channel通道方法 31 | Future _getBatteryLevel() async { 32 | String batteryLevel; 33 | try { 34 | final int result = await platform.invokeMethod('getBatteryLevel'); 35 | batteryLevel = 'Battery level at $result % .'; 36 | } on PlatformException catch (e) { 37 | batteryLevel = "Failed to get battery level: '${e.message}'."; 38 | } 39 | 40 | setState(() { 41 | _batteryLevel = batteryLevel; 42 | }); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | // TODO: implement build 48 | return Scaffold( 49 | appBar: AppBar( 50 | centerTitle: true, 51 | title: Text("Channel"), 52 | ), 53 | body: Center( 54 | child: Column( 55 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 56 | children: [ 57 | RaisedButton( 58 | child: Text('获得电池电量'), 59 | onPressed: _getBatteryLevel, 60 | ), 61 | new Text(_batteryLevel), 62 | ], 63 | ), 64 | ), 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/pages/dart/dart_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 dart相关demo 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2020-04-04 6 | * 7 | */ 8 | import 'package:flutter/material.dart'; 9 | class DartPage extends StatelessWidget{ 10 | @override 11 | Widget build(BuildContext context) { 12 | // TODO: implement build 13 | return Scaffold( 14 | appBar: AppBar( 15 | centerTitle: true, 16 | title: Text("Dart"), 17 | ), 18 | body: Container( 19 | child: Text("I am Dart"), 20 | ), 21 | ); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /lib/pages/main/about_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 关于 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2020-04-04 6 | * 7 | */ 8 | /// 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_study_app/res/colors.dart'; 11 | import 'package:flutter_study_app/res/string_zh.dart'; 12 | import 'package:flutter_study_app/utils/toast_util.dart'; 13 | import 'package:share/share.dart'; 14 | import 'package:url_launcher/url_launcher.dart'; 15 | 16 | class AboutPage extends StatelessWidget { 17 | @override 18 | Widget build(BuildContext context) { 19 | // TODO: implement build 20 | return Scaffold( 21 | backgroundColor: Color(0xfff2f2f2), 22 | appBar: AppBar( 23 | centerTitle: true, 24 | title: Text("关于"), 25 | ), 26 | body: Container( 27 | margin: EdgeInsets.all(20), 28 | padding: EdgeInsets.all(20), 29 | alignment: Alignment.topLeft, 30 | decoration: BoxDecoration( 31 | color: Colors.white, 32 | borderRadius: BorderRadius.circular(10), 33 | ), 34 | child: Column( 35 | crossAxisAlignment: CrossAxisAlignment.start, 36 | children: [ 37 | Text(StringZh.appDesc), 38 | SizedBox( 39 | height: 20, 40 | ), 41 | Text("项目地址:"), 42 | InkWell( 43 | onTap: () { 44 | _launchURL(StringZh.appAddress); 45 | }, 46 | child: Text( 47 | StringZh.appAddress, 48 | style: TextStyle(color: Colors.blue, fontSize: 18), 49 | ), 50 | ) 51 | ], 52 | ), 53 | ), 54 | floatingActionButton: FloatingActionButton( 55 | child: Icon(Icons.share), 56 | onPressed: () { 57 | Share.share(StringZh.appDesc+"\n\n项目地址:"+StringZh.appAddress); 58 | }, 59 | tooltip: "放开我,按这么长时间干嘛!!!", 60 | backgroundColor: AppColors.primaryColor, 61 | ), 62 | ); 63 | } 64 | 65 | _launchURL(String url) async { 66 | if (await canLaunch(url)) { 67 | await launch(url); 68 | } else { 69 | ToastUtil.showToast('Could not launch $url'); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/pages/main/drawer_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 侧滑页面 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019/7/13 6 | * 7 | */ 8 | import 'package:fluro/fluro.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_study_app/routers/application.dart'; 11 | import 'package:flutter_study_app/routers/routers.dart'; 12 | import 'package:flutter_study_app/utils/toast_util.dart'; 13 | 14 | class DrawerPage extends StatelessWidget { 15 | @override 16 | Widget build(BuildContext context) { 17 | // TODO: implement build 18 | return Scaffold( 19 | body: Column( 20 | children: [ 21 | UserAccountsDrawerHeader( 22 | accountName: Text( 23 | '程序猿在广东', 24 | style: TextStyle(fontWeight: FontWeight.bold), 25 | ), 26 | accountEmail: Text( 27 | '这个世界不属于90后,只属于努力后!微信搜索 程序猿在广东,了解更多', 28 | maxLines: 2, 29 | ), 30 | currentAccountPicture: CircleAvatar( 31 | backgroundImage: AssetImage('assets/images/logo.jpg'), 32 | ), 33 | margin: EdgeInsets.zero, 34 | ), 35 | Expanded( 36 | child: ListView( 37 | children: [ 38 | _listItem(Icon(Icons.brightness_medium), Text("主题"), () { 39 | ToastUtil.showToast("功能开发中~"); 40 | }), 41 | _listItem(Icon(Icons.people), Text("GitHub"), () { 42 | //WebView(flutter_webview_plugin) 43 | Application.router.navigateTo( 44 | context, 45 | '${Routes.webViewPlginPage}?url=${Uri.encodeComponent("https://github.com/ChessLuo")}&title=My GitHub', 46 | transition: TransitionType.native, 47 | ); 48 | }), 49 | _listItem(Icon(Icons.android), Text("关于"), () { 50 | Application.router.navigateTo( 51 | context, 52 | Routes.aboutPage, 53 | transition: TransitionType.inFromRight, 54 | ); 55 | }), 56 | ], 57 | ), 58 | ) 59 | ], 60 | ), 61 | ); 62 | } 63 | 64 | Widget _listItem(Icon leading, Widget title, onTap) { 65 | return Container( 66 | child: ListTile( 67 | leading: leading, 68 | title: title, 69 | trailing: Icon(Icons.keyboard_arrow_right), 70 | onTap: onTap, 71 | ), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/pages/main/home_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_study_app/common/model/func_model.dart'; 4 | import 'package:flutter_study_app/res/string_zh.dart'; 5 | import 'package:flutter_study_app/routers/application.dart'; 6 | import 'package:flutter_study_app/routers/routers.dart'; 7 | 8 | class HomePage extends StatefulWidget { 9 | @override 10 | State createState() { 11 | return _HomePageState(); 12 | } 13 | } 14 | 15 | class _HomePageState extends State { 16 | List itemTitles = [ 17 | FuncModel( 18 | name: StringZh.dart, bgColor: Colors.red, routePath: Routes.dartPage), 19 | FuncModel( 20 | name: '常用Widget', 21 | bgColor: Colors.orange, 22 | routePath: Routes.widgetsPage), 23 | FuncModel(name: '状态管理', bgColor: Colors.amber, routePath: Routes.statePage), 24 | FuncModel( 25 | name: 'Canvas与动画', bgColor: Colors.green, routePath: Routes.animPage), 26 | FuncModel( 27 | name: '本地数据存储', bgColor: Colors.cyan, routePath: Routes.localCachePage), 28 | FuncModel( 29 | name: 'Flutter Channel', 30 | bgColor: Colors.blue, 31 | routePath: Routes.flutterChannel), 32 | FuncModel( 33 | name: StringZh.otherDemo, 34 | bgColor: Colors.purple, 35 | routePath: Routes.otherListPage), 36 | ]; 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | return Container( 41 | padding: EdgeInsets.all(20), 42 | child: ListView.builder( 43 | itemCount: itemTitles.length, 44 | itemBuilder: (BuildContext context, int index) { 45 | return _listItem( 46 | itemTitles[index].name, itemTitles[index].bgColor, () { 47 | Application.router.navigateTo( 48 | context, itemTitles[index].routePath, 49 | transition: TransitionType.inFromRight); 50 | }); 51 | })); 52 | } 53 | 54 | Widget _listItem(String title, Color bgColor, onTap) { 55 | return GestureDetector( 56 | onTap: onTap, 57 | child: Container( 58 | alignment: Alignment.center, 59 | margin: EdgeInsets.only(bottom: 20), 60 | padding: EdgeInsets.only(top: 20, bottom: 20), 61 | decoration: BoxDecoration( 62 | color: bgColor, 63 | borderRadius: BorderRadius.circular(10), 64 | ), 65 | child: Text( 66 | title, 67 | style: TextStyle( 68 | color: Colors.white, 69 | fontSize: 20, 70 | ), 71 | )), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/pages/main/main_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 主页 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019/7/21 6 | * 7 | */ 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_study_app/pages/main/drawer_page.dart'; 10 | import 'package:flutter_study_app/pages/main/home_page.dart'; 11 | import 'package:flutter_study_app/provider/color_filtered_model.dart'; 12 | import 'package:flutter_study_app/res/colors.dart'; 13 | import 'package:flutter_study_app/res/string_zh.dart'; 14 | import 'package:flutter_study_app/utils/toast_util.dart'; 15 | import 'package:provider/provider.dart'; 16 | import 'package:share/share.dart'; 17 | 18 | class MainPage extends StatefulWidget { 19 | @override 20 | State createState() { 21 | // TODO: implement createState 22 | return _MainPageState(); 23 | } 24 | } 25 | 26 | class _MainPageState extends State { 27 | final GlobalKey _scaffoldKey = GlobalKey(); 28 | String actionTxt = "变灰"; 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | //获取filteredProvider实例 33 | var filteredProvider = Provider.of(context); 34 | return Scaffold( 35 | key: _scaffoldKey, 36 | backgroundColor: Color(0xfff2f2f2), 37 | appBar: AppBar( 38 | centerTitle: true, 39 | title: Text( 40 | '学无止境', 41 | style: TextStyle(color: Colors.white), 42 | ), 43 | actions: [ 44 | InkWell( 45 | onTap: (){ 46 | if(filteredProvider.currentColor==Colors.transparent){ 47 | actionTxt = "切回"; 48 | filteredProvider.currColorFiltered(Colors.grey); 49 | }else{ 50 | actionTxt = "变灰"; 51 | filteredProvider.currColorFiltered(Colors.transparent); 52 | } 53 | 54 | }, 55 | child: Container( 56 | margin: EdgeInsets.only(right: 16), 57 | alignment: Alignment.center, 58 | child: Text(actionTxt), 59 | ), 60 | ) 61 | ], 62 | ), 63 | body: HomePage(), 64 | drawer: Drawer( 65 | child: DrawerPage(), //侧滑页面 66 | ), 67 | floatingActionButton: FloatingActionButton( 68 | child: Icon(Icons.share), 69 | onPressed: () { 70 | Share.share(StringZh.appDesc+"\n\n项目地址:"+StringZh.appAddress); 71 | }, 72 | tooltip: "放开我,按这么长时间干嘛!!!", 73 | backgroundColor: AppColors.primaryColor, 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/pages/other/demo/event_bus_demo.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 这个世界不属不属于90后,只属于努力后! 3 | * @author ChessLuo 4 | * @github https://github.com/ChessLuo 5 | * @email superluo666@gmail.com 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_study_app/common/events.dart'; 10 | import 'package:fluttertoast/fluttertoast.dart'; 11 | 12 | class EventBusPage extends StatefulWidget { 13 | @override 14 | State createState() { 15 | // TODO: implement createState 16 | return _EventBusPageState(); 17 | } 18 | } 19 | 20 | class _EventBusPageState extends State { 21 | TextEditingController _colorController = new TextEditingController(); 22 | 23 | @override 24 | void initState() { 25 | super.initState(); 26 | // 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | // TODO: implement build 32 | return Scaffold( 33 | appBar: AppBar( 34 | centerTitle: true, 35 | iconTheme: IconThemeData(color: Colors.white), 36 | title: Text( 37 | "eventbus事件总线", 38 | style: TextStyle(color: Colors.white), 39 | ), 40 | ), 41 | body: Container( 42 | padding: EdgeInsets.all(20), 43 | child: Column( 44 | children: [ 45 | Center( 46 | child: Text( 47 | "eventbus事件总线输入颜色值修改APP主题色", 48 | style: TextStyle(fontSize: 14, color: Color(0xff666666)), 49 | ), 50 | ), 51 | Padding(padding: EdgeInsets.only(top: 10)), 52 | _getColorInputView(), 53 | Padding(padding: EdgeInsets.only(top: 10)), 54 | _getBottonView(), 55 | ], 56 | ), 57 | ), 58 | ); 59 | } 60 | 61 | _getColorInputView() { 62 | return TextField( 63 | keyboardType: TextInputType.text, 64 | style: TextStyle(color: Color(0xFF888888)), 65 | controller: _colorController, 66 | decoration: InputDecoration( 67 | hintText: "输入正确的颜色值,如黑色:#000000", 68 | hintStyle: TextStyle(color: Color(0xFF888888)), 69 | contentPadding: 70 | EdgeInsets.only(left: 10, right: 10, bottom: 10, top: 10), 71 | border: OutlineInputBorder( 72 | borderRadius: BorderRadius.circular(8.0), 73 | ), 74 | ), 75 | ); 76 | } 77 | 78 | _getBottonView() { 79 | return RaisedButton( 80 | onPressed: () { 81 | if (_colorController.text == null || _colorController.text == "") { 82 | Fluttertoast.showToast(msg: "请输入正确的颜色值"); 83 | return; 84 | } 85 | print(_colorController.text); 86 | //发送订阅消息去修改颜色 87 | eventBus.fire(ThemeColorEvent(_colorController.text)); 88 | }, 89 | child: Text( 90 | "确定", 91 | style: TextStyle(color: Colors.white, fontSize: 18), 92 | ), 93 | color: Colors.orange, 94 | shape: RoundedRectangleBorder( 95 | borderRadius: BorderRadius.circular(5), 96 | )); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /lib/pages/other/demo/file_zip_demo.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | /** 4 | * @描述 文件解/压缩 5 | * @author chessluo 6 | * @email superluo666@gmail.com 7 | * @date 2019/6/13 8 | * 9 | */ 10 | import 'package:flutter/material.dart'; 11 | import 'package:archive/archive.dart'; 12 | import 'package:archive/archive_io.dart'; 13 | import 'package:path_provider/path_provider.dart'; 14 | import 'package:fluttertoast/fluttertoast.dart'; 15 | import 'package:permission_handler/permission_handler.dart'; 16 | 17 | class FileZipDemo extends StatefulWidget { 18 | @override 19 | State createState() { 20 | // TODO: implement createState 21 | return _FileZipDemoState(); 22 | } 23 | } 24 | 25 | class _FileZipDemoState extends State { 26 | String _zipRootPath = "空"; 27 | TextEditingController _zipNameController = new TextEditingController(); 28 | TextEditingController _unZipNameController = new TextEditingController(); 29 | int _tag; //0表示解压、1表示压缩 30 | 31 | @override 32 | void initState() { 33 | // TODO: implement initState 34 | super.initState(); 35 | _getRootPath(); 36 | } 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | // TODO: implement build 41 | return Scaffold( 42 | appBar: AppBar( 43 | centerTitle: true, 44 | title: Text("文件解/压缩"), 45 | ), 46 | body: Container( 47 | padding: EdgeInsets.all(8), 48 | child: Column( 49 | crossAxisAlignment: CrossAxisAlignment.start, 50 | children: [ 51 | Text("手机存储根目录:"), 52 | Text( 53 | _zipRootPath, 54 | ), 55 | Padding(padding: EdgeInsets.only(top: 20)), 56 | Text("1、输入手机存储根目录下的需要解压的文件名称"), 57 | _getZipNameView(0), 58 | _getQueryBtnView(0), 59 | Padding(padding: EdgeInsets.only(top: 10)), 60 | Text("2、输入手机存储根目录下的需要压缩的文件名称"), 61 | _getZipNameView(1), 62 | _getQueryBtnView(1), 63 | ], 64 | ), 65 | ), 66 | ); 67 | } 68 | 69 | _getZipNameView(int tag) { 70 | return TextField( 71 | keyboardType: TextInputType.text, 72 | style: TextStyle(color: Color(0xFF888888)), 73 | controller: tag == 0 ? _unZipNameController : _zipNameController, 74 | decoration: InputDecoration( 75 | hintText: tag == 0 ? "压缩包文件名称 格式如:test.zip" : "待压缩文件名称 格式如:test", 76 | hintStyle: TextStyle(color: Color(0xFF888888)), 77 | contentPadding: 78 | EdgeInsets.only(left: 10, right: 10, bottom: 10, top: 10), 79 | border: OutlineInputBorder( 80 | borderRadius: BorderRadius.circular(8.0), 81 | ), 82 | ), 83 | ); 84 | } 85 | 86 | _getQueryBtnView(int tag) { 87 | return Container( 88 | alignment: Alignment.center, 89 | child: RaisedButton( 90 | onPressed: () async { 91 | //需要存储权限 92 | if (await Permission.storage.request().isGranted) { 93 | //开始解压或压缩 94 | tag == 0 ? _unZip() : _zip(); 95 | } 96 | 97 | // You can request multiple permissions at once. 98 | // Map statuses = await [ 99 | // Permission.storage, 100 | // ].request(); 101 | // print(statuses[Permission.storage]); 102 | }, 103 | child: Text( 104 | tag == 0 ? "解压" : "压缩", 105 | style: TextStyle(color: Colors.white, fontSize: 18), 106 | ), 107 | color: Colors.orange, 108 | shape: RoundedRectangleBorder( 109 | borderRadius: BorderRadius.circular(5), 110 | )), 111 | ); 112 | } 113 | 114 | ///解压 115 | void _unZip() async { 116 | if (_unZipNameController.text == null || _unZipNameController.text == "") { 117 | Fluttertoast.showToast(msg: "压缩包文件名称不能为空!"); 118 | return; 119 | } 120 | String zipFilePath = _zipRootPath + "/" + _unZipNameController.text; 121 | if (!File(zipFilePath).existsSync()) { 122 | Fluttertoast.showToast(msg: "压缩包文件不存在!"); 123 | return; 124 | } 125 | 126 | // 从磁盘读取Zip文件。 127 | List bytes = File(zipFilePath).readAsBytesSync(); 128 | // 解码Zip文件 129 | Archive archive = ZipDecoder().decodeBytes(bytes); 130 | 131 | // 将Zip存档的内容解压缩到磁盘。 132 | for (ArchiveFile file in archive) { 133 | if (file.isFile) { 134 | List data = file.content; 135 | File(_zipRootPath + "/" + file.name) 136 | ..createSync(recursive: true) 137 | ..writeAsBytesSync(data); 138 | } else { 139 | Directory(_zipRootPath + "/" + file.name)..create(recursive: true); 140 | } 141 | } 142 | Fluttertoast.showToast(msg: "解压成功"); 143 | print("解压成功"); 144 | } 145 | 146 | ///压缩 147 | void _zip() async { 148 | if (_zipNameController.text == null || _zipNameController.text == "") { 149 | Fluttertoast.showToast(msg: "待压缩文件名称不能为空!"); 150 | return; 151 | } 152 | String directory = _zipRootPath + "/" + _zipNameController.text; 153 | if (!Directory(directory).existsSync()) { 154 | Fluttertoast.showToast(msg: "待压缩文件不存在!"); 155 | return; 156 | } 157 | 158 | // Zip a directory to out.zip using the zipDirectory convenience method 159 | //使用zipDirectory方法将目录压缩到xxx.zip 160 | var encoder = ZipFileEncoder(); 161 | encoder.zipDirectory(Directory(directory), filename: directory + ".zip"); 162 | Fluttertoast.showToast(msg: "压缩成功"); 163 | //手动创建目录和单个文件的zip。 164 | // encoder.create('out2.zip'); 165 | // encoder.addDirectory(Directory('out')); 166 | // encoder.addFile(File('test.zip')); 167 | // encoder.close(); 168 | } 169 | 170 | void _getRootPath() async { 171 | String pathStr = (await getExternalStorageDirectory()).path; 172 | setState(() { 173 | _zipRootPath = pathStr; 174 | }); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /lib/pages/other/demo/flutter_webview_demo.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 flutter官方webview 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019/7/13 6 | * 7 | */ 8 | import 'dart:async'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:fluttertoast/fluttertoast.dart'; 11 | import 'package:webview_flutter/webview_flutter.dart'; 12 | 13 | class FlutterWebView extends StatefulWidget { 14 | final String url; 15 | final String barTitle; 16 | 17 | const FlutterWebView({Key key, this.url, this.barTitle}) : super(key: key); 18 | 19 | @override 20 | State createState() { 21 | return WebViewState(); 22 | } 23 | } 24 | 25 | class WebViewState extends State 26 | with AutomaticKeepAliveClientMixin { 27 | String _webUrl; 28 | 29 | @override 30 | void initState() { 31 | super.initState(); 32 | _webUrl = Uri.decodeComponent(widget.url); 33 | 34 | print("web url == $_webUrl"); 35 | } 36 | 37 | ///js与flutter交互 38 | JavascriptChannel _alertJavascriptChannel(BuildContext context) { 39 | return JavascriptChannel( 40 | name: 'invoke', //invoke要和网页协商一致 41 | onMessageReceived: (JavascriptMessage message) { 42 | print(message.message); 43 | }); 44 | } 45 | 46 | ///组合脚本执行方法,将数据发送给js端(flutter与js交互) 47 | void _onExecJavascript(String url) async { 48 | _controller.future.then((controller) { 49 | controller.loadUrl(url); 50 | }); 51 | //或者 evaluateJavascript('callJS("js方法")') 52 | } 53 | 54 | final Completer _controller = 55 | Completer(); 56 | 57 | bool _loading = true; //等待 58 | 59 | @override 60 | Widget build(BuildContext context) { 61 | return Scaffold( 62 | appBar: AppBar( 63 | title: Text( 64 | widget.barTitle, 65 | ), 66 | centerTitle: true, 67 | ), 68 | body: SafeArea( 69 | //设置安全区域 ,不沉浸式 70 | top: true, 71 | child: Builder(builder: (BuildContext context) { 72 | return Stack( 73 | children: [ 74 | _showWebView(context), 75 | _loading 76 | ? Center( 77 | child: CircularProgressIndicator(), 78 | ) 79 | : Container(), 80 | ], 81 | ); 82 | }), 83 | )); 84 | } 85 | 86 | @override 87 | // TODO: implement wantKeepAlive 88 | bool get wantKeepAlive => true; 89 | 90 | ///初始化webview显示 91 | Widget _showWebView(BuildContext context) { 92 | return WebView( 93 | initialUrl: widget.url, 94 | 95 | ///初始化url 96 | javascriptMode: JavascriptMode.unrestricted, 97 | 98 | ///JS执行模式 99 | onWebViewCreated: (WebViewController webViewController) { 100 | ///在WebView创建完成后调用,只会被调用一次 101 | // 102 | // 103 | _controller.complete(webViewController); 104 | }, 105 | javascriptChannels: [ 106 | ///JS和Flutter通信的Channel; 107 | _alertJavascriptChannel(context), 108 | ].toSet(), 109 | navigationDelegate: (NavigationRequest request) { 110 | //路由委托(可以通过在此处拦截url实现JS调用Flutter部分); 111 | ///通过拦截url来实现js与flutter交互 112 | if (request.url.startsWith('js://webview')) { 113 | Fluttertoast.showToast(msg: 'JS调用了Flutter By navigationDelegate'); 114 | print('blocking navigation to $request}'); 115 | return NavigationDecision.prevent; 116 | 117 | ///阻止路由替换,不能跳转,因为这是js交互给我们发送的消息 118 | } 119 | 120 | return NavigationDecision.navigate; 121 | 122 | ///允许路由替换 123 | }, 124 | onPageFinished: (String url) { 125 | ///页面加载完成回调 126 | setState(() { 127 | _loading = false; 128 | }); 129 | print('Page finished loading: $url'); 130 | }, 131 | ); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /lib/pages/other/demo/url_launcher_demo.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 用于在移动平台中启动URL。 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019-11-03 6 | * 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:url_launcher/url_launcher.dart'; 11 | 12 | class UrlLauncherDemo extends StatefulWidget { 13 | @override 14 | State createState() { 15 | // TODO: implement createState 16 | return _UrlLauncherState(); 17 | } 18 | } 19 | 20 | class _UrlLauncherState extends State { 21 | String _rel = ""; 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | // TODO: implement build 26 | return Scaffold( 27 | appBar: AppBar( 28 | centerTitle: true, 29 | title: Text("url_launcher"), 30 | ), 31 | body: Container( 32 | alignment: Alignment.topCenter, 33 | margin: EdgeInsets.all(15), 34 | child: Column( 35 | children: [ 36 | Container( 37 | margin: EdgeInsets.only(bottom: 4), 38 | child: RaisedButton( 39 | onPressed: () { 40 | const url = 'tel:110'; 41 | _launchURL(url); 42 | }, 43 | child: Text("拨打电话给我吧!没事别骚扰我"), 44 | ), 45 | ), 46 | Container( 47 | margin: EdgeInsets.only(bottom: 4), 48 | child: RaisedButton( 49 | onPressed: () { 50 | const url = 'sms:13166688899'; 51 | _launchURL(url); 52 | }, 53 | child: Text("发送短信"), 54 | )), 55 | Container( 56 | margin: EdgeInsets.only(bottom: 4), 57 | child: RaisedButton( 58 | onPressed: () { 59 | const url = 60 | 'mailto:superluo666@gmail.com?subject=Test&body=测试跳转发送邮件'; 61 | _launchURL(url); 62 | }, 63 | child: Text("发送邮件"), 64 | )), 65 | Container( 66 | margin: EdgeInsets.only(bottom: 4), 67 | child: RaisedButton( 68 | onPressed: () { 69 | const url = 'https://github.com/ChessLuo/flutter_study_app'; 70 | _launchURL(url); 71 | }, 72 | child: Text("默认浏览器中打开URL"), 73 | ), 74 | ), 75 | Container( 76 | margin: EdgeInsets.only(bottom: 4), 77 | child: RaisedButton( 78 | onPressed: () { 79 | const url = 'weixin://'; 80 | _launchURL(url); 81 | }, 82 | child: Text("打开微信。搜索程序猿在广东"), 83 | ), 84 | ), 85 | Container( 86 | margin: EdgeInsets.only(bottom: 4), 87 | child: RaisedButton( 88 | onPressed: () { 89 | const url = 90 | 'mqqwpa://im/chat?chat_type=wpa&uin=123456'; //uin是发送过去的qq号码 91 | _launchURL(url); 92 | }, 93 | child: Text("打开QQ"), 94 | ), 95 | ), 96 | Container( 97 | margin: EdgeInsets.only(bottom: 4), 98 | child: RaisedButton( 99 | onPressed: () { 100 | const url = 'taobao://item.taobao.com/item.html?id=443534567'; 101 | _launchURL(url); 102 | }, 103 | child: Text("打开淘宝"), 104 | ), 105 | ), 106 | Container( 107 | margin: EdgeInsets.only(bottom: 4), 108 | child: RaisedButton( 109 | onPressed: () { 110 | const url = 'baidumap://map/marker'; 111 | _launchURL(url); 112 | }, 113 | child: Text("打开百度地图"), 114 | ), 115 | ), 116 | Container( 117 | margin: EdgeInsets.only(bottom: 4), 118 | child: RaisedButton( 119 | onPressed: () { 120 | const url = 'androidamap://viewMap'; 121 | _launchURL(url); 122 | }, 123 | child: Text("打开高德地图"), 124 | ), 125 | ), 126 | Text(_rel), 127 | ], 128 | ), 129 | ), 130 | ); 131 | } 132 | 133 | _launchURL(String url) async { 134 | if (await canLaunch(url)) { 135 | await launch(url); 136 | } else { 137 | setState(() { 138 | _rel = 'Could not launch $url'; 139 | }); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /lib/pages/other/demo/webview_plugin_demo.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 原生webview 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2020-04-04 6 | * 7 | */ 8 | import 'dart:async'; 9 | 10 | import 'package:flutter/material.dart'; 11 | import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; 12 | 13 | class WebViewPlgin extends StatefulWidget { 14 | final String url; //web地址 15 | final String title; //标题 16 | 17 | WebViewPlgin({ 18 | this.url, 19 | this.title = "详情", 20 | }); 21 | 22 | @override 23 | _WebViewState createState() => _WebViewState(); 24 | } 25 | 26 | class _WebViewState extends State { 27 | final flutterWebviewPlugin = FlutterWebviewPlugin(); 28 | StreamSubscription _onUrlChanged; 29 | StreamSubscription _onStateChanged; 30 | StreamSubscription _onHttpError; 31 | 32 | @override 33 | void initState() { 34 | super.initState(); 35 | print("web url == ${widget.url}"); 36 | 37 | flutterWebviewPlugin.close(); 38 | _onUrlChanged = flutterWebviewPlugin.onUrlChanged.listen((String url) {}); 39 | _onStateChanged = flutterWebviewPlugin.onStateChanged 40 | .listen((WebViewStateChanged state) {}); 41 | _onHttpError = 42 | flutterWebviewPlugin.onHttpError.listen((WebViewHttpError error) { 43 | print(error); 44 | }); 45 | } 46 | 47 | @override 48 | void dispose() { 49 | _onStateChanged.cancel(); 50 | _onUrlChanged.cancel(); 51 | _onHttpError.cancel(); 52 | flutterWebviewPlugin.dispose(); 53 | super.dispose(); 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | return Scaffold( 59 | appBar: AppBar( 60 | centerTitle: true, 61 | title: Text(widget.title), 62 | ), 63 | body: WebviewScaffold( 64 | url: widget.url, 65 | withZoom: false, 66 | hidden: true, 67 | initialChild: Container( 68 | color: Colors.white, 69 | child: Center( 70 | child: CircularProgressIndicator(), 71 | ), 72 | ), 73 | ignoreSSLErrors: true, 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/pages/other/other_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 其他demo列表 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019-11-03 6 | * 7 | */ 8 | /// 9 | import 'package:fluro/fluro.dart'; 10 | import 'package:flutter/material.dart'; 11 | import 'package:flutter_study_app/common/model/func_model.dart'; 12 | import 'package:flutter_study_app/routers/application.dart'; 13 | import 'package:flutter_study_app/routers/routers.dart'; 14 | 15 | class OtherDemoList extends StatefulWidget { 16 | @override 17 | State createState() { 18 | return _ListViewState(); 19 | } 20 | } 21 | 22 | class _ListViewState extends State { 23 | List itemTitles = [ 24 | FuncModel(name: 'eventbus事件总线', routePath: Routes.eventBusPage), 25 | FuncModel(name: '文件解压缩', routePath: Routes.fileZipPage), 26 | FuncModel( 27 | name: 'WebView(flutter_webview_plugin)', 28 | routePath: 29 | '${Routes.webViewPlginPage}?url=${Uri.encodeComponent("https://github.com/ChessLuo")}&title=flutter_webview_plugin'), 30 | FuncModel( 31 | name: 'WebView(flutter官方插件)', 32 | routePath: 33 | '${Routes.flutterWebViewPage}?url=${Uri.encodeComponent("https://github.com/ChessLuo")}&title=flutter_webview'), 34 | FuncModel(name: 'url_launcher', routePath: Routes.urlLauncher), 35 | ]; 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | appBar: AppBar( 41 | centerTitle: true, 42 | title: Text("其他Demo"), 43 | ), 44 | body: ListView.builder( 45 | itemCount: itemTitles.length, 46 | itemBuilder: (BuildContext context, int index) { 47 | return _listItem(itemTitles[index].name, () { 48 | Application.router.navigateTo( 49 | context, itemTitles[index].routePath, 50 | transition: TransitionType.inFromRight); 51 | }); 52 | }), 53 | ); 54 | } 55 | 56 | ///demo Item入口View 57 | Widget _listItem(String itemTitle, Function onTap) { 58 | return Container( 59 | decoration: BoxDecoration( 60 | color: Colors.white, 61 | border: BorderDirectional( 62 | bottom: BorderSide(color: Colors.grey, width: 0.5))), 63 | child: ListTile( 64 | title: Text(itemTitle), 65 | trailing: Icon(Icons.keyboard_arrow_right), 66 | onTap: onTap, 67 | ), 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/pages/state/provider_demo/navigationbar_model.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 创建provider 数据模型 3 | * 4 | * 这里的 Model 实际上就是我们的状态, 5 | * 它不仅储存了我们的数据模型,而且还包含了更改数据的方法,并暴露出它想要暴露出的数据 6 | * 7 | * @author chessluo 8 | * @email superluo666@gmail.com 9 | * @date 2019/7/23 10 | * 11 | */ 12 | import 'package:flutter/material.dart'; 13 | 14 | class BottomNavigationBarProvider with ChangeNotifier { 15 | int _currentIndex = 0; 16 | 17 | get currentIndex => _currentIndex; 18 | 19 | set currentIndex(int index) { 20 | _currentIndex = index; 21 | notifyListeners(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/pages/state/provider_demo/provider_demo.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 provider 状态管理 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2019/7/21 6 | * 7 | */ 8 | import 'package:flutter/material.dart'; 9 | import 'package:provider/provider.dart'; 10 | 11 | import 'navigationbar_model.dart'; 12 | 13 | class ProviderDemoPage extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text("provider状态管理"), 19 | centerTitle: true, 20 | ), 21 | body: ChangeNotifierProvider( 22 | ///provider绑定数据 23 | child: BottomNavigationBarExample(), 24 | create: (BuildContext context) => BottomNavigationBarProvider(), 25 | ), 26 | ); 27 | } 28 | } 29 | 30 | ///创建底部菜单view 31 | class BottomNavigationBarExample extends StatefulWidget { 32 | @override 33 | _BottomNavigationBarExampleState createState() => 34 | _BottomNavigationBarExampleState(); 35 | } 36 | 37 | class _BottomNavigationBarExampleState 38 | extends State { 39 | var currentTab = [ 40 | Home(), 41 | Profile(), 42 | Setting(), 43 | ]; 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | ///provider获取数据 48 | var provider = Provider.of(context); 49 | return Scaffold( 50 | body: currentTab[provider.currentIndex], 51 | bottomNavigationBar: BottomNavigationBar( 52 | currentIndex: provider.currentIndex, //获取当前index 53 | onTap: (index) { 54 | provider.currentIndex = index; //设置当前index 55 | }, 56 | items: [ 57 | BottomNavigationBarItem( 58 | icon: new Icon(Icons.home), 59 | title: new Text('Home'), 60 | ), 61 | BottomNavigationBarItem( 62 | icon: new Icon(Icons.person), 63 | title: new Text('Profile'), 64 | ), 65 | BottomNavigationBarItem( 66 | icon: Icon(Icons.settings), 67 | title: Text('Settings'), 68 | ) 69 | ], 70 | ), 71 | ); 72 | } 73 | } 74 | 75 | class Home extends StatelessWidget { 76 | @override 77 | Widget build(BuildContext context) { 78 | return Scaffold( 79 | body: Center( 80 | child: Container( 81 | alignment: Alignment.center, 82 | height: 300, 83 | width: 300, 84 | child: Text( 85 | "Home", 86 | style: TextStyle(color: Colors.white, fontSize: 30), 87 | ), 88 | color: Colors.amber, 89 | )), 90 | ); 91 | } 92 | } 93 | 94 | class Profile extends StatelessWidget { 95 | @override 96 | Widget build(BuildContext context) { 97 | return Scaffold( 98 | body: Center( 99 | child: Container( 100 | alignment: Alignment.center, 101 | height: 300, 102 | width: 300, 103 | child: Text( 104 | "Profile", 105 | style: TextStyle(color: Colors.white, fontSize: 30), 106 | ), 107 | color: Colors.blue, 108 | ), 109 | ), 110 | ); 111 | } 112 | } 113 | 114 | class Setting extends StatelessWidget { 115 | @override 116 | Widget build(BuildContext context) { 117 | return Scaffold( 118 | body: Center( 119 | child: Container( 120 | alignment: Alignment.center, 121 | height: 300, 122 | width: 300, 123 | child: Text( 124 | "Settings", 125 | style: TextStyle(color: Colors.white, fontSize: 30), 126 | ), 127 | color: Colors.cyan, 128 | )), 129 | ); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /lib/pages/state/state_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 状态管理相关demo 3 | * provider、flutter_redux、bloc等 4 | * @author chessluo 5 | * @email superluo666@gmail.com 6 | * @date 2019-11-03 7 | * 8 | */ 9 | /// 10 | import 'package:fluro/fluro.dart'; 11 | import 'package:flutter/material.dart'; 12 | import 'package:flutter_study_app/common/model/func_model.dart'; 13 | import 'package:flutter_study_app/routers/application.dart'; 14 | import 'package:flutter_study_app/routers/routers.dart'; 15 | 16 | class StateDemoList extends StatefulWidget { 17 | @override 18 | State createState() { 19 | return _ListViewState(); 20 | } 21 | } 22 | 23 | class _ListViewState extends State { 24 | List itemTitles = [ 25 | FuncModel(name: 'provider状态管理', routePath: Routes.providerPage), 26 | ]; 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar( 32 | centerTitle: true, 33 | title: Text("状态管理"), 34 | ), 35 | body: ListView.builder( 36 | itemCount: itemTitles.length, 37 | itemBuilder: (BuildContext context, int index) { 38 | return _listItem(itemTitles[index].name, () { 39 | Application.router.navigateTo( 40 | context, itemTitles[index].routePath, 41 | transition: TransitionType.inFromRight); 42 | }); 43 | }), 44 | ); 45 | } 46 | 47 | ///demo Item入口View 48 | Widget _listItem(String itemTitle, Function onTap) { 49 | return Container( 50 | decoration: BoxDecoration( 51 | color: Colors.white, 52 | border: BorderDirectional(bottom: BorderSide(color: Colors.grey))), 53 | child: ListTile( 54 | title: Text(itemTitle), 55 | trailing: Icon(Icons.keyboard_arrow_right), 56 | onTap: onTap, 57 | ), 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/pages/transition_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:fluro/fluro.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_study_app/routers/application.dart'; 6 | import 'package:flutter_study_app/routers/routers.dart'; 7 | /** 8 | *
 9 |  *     author: ChessLuo
10 |  *     email superluo666@gmail.com
11 |  *     desc  : 启动页动画
12 |  * 
13 | */ 14 | /// 15 | class TransitionPage extends StatefulWidget { 16 | @override 17 | State createState() { 18 | // TODO: implement createState 19 | return TransitionPageState(); 20 | } 21 | } 22 | 23 | class TransitionPageState extends State 24 | with SingleTickerProviderStateMixin { 25 | var _visible = true; 26 | 27 | AnimationController animationController; 28 | Animation animation; 29 | 30 | startTime() async { 31 | var _duration = new Duration(seconds: 3); 32 | return new Timer(_duration, toHome); 33 | } 34 | 35 | void toHome() { 36 | // Navigator.of(context).pushReplacementNamed(Constant.HOME_PAGE); 37 | Application.router.navigateTo(context, Routes.mainPage, 38 | replace: true, transition: TransitionType.inFromRight); 39 | } 40 | 41 | @override 42 | void initState() { 43 | super.initState(); 44 | animationController = new AnimationController( 45 | vsync: this, duration: new Duration(seconds: 2)); 46 | animation = 47 | new CurvedAnimation(parent: animationController, curve: Curves.easeOut); 48 | 49 | animation.addListener(() => this.setState(() {})); 50 | animationController.forward(); 51 | 52 | setState(() { 53 | _visible = !_visible; 54 | }); 55 | startTime(); 56 | } 57 | 58 | @override 59 | Widget build(BuildContext context) { 60 | return Scaffold( 61 | backgroundColor: Colors.white, 62 | body: Stack( 63 | fit: StackFit.expand, 64 | children: [ 65 | new Column( 66 | mainAxisAlignment: MainAxisAlignment.end, 67 | mainAxisSize: MainAxisSize.min, 68 | children: [ 69 | Padding( 70 | padding: EdgeInsets.only(bottom: 50.0), 71 | child: Text( 72 | "程序猿在广东", 73 | style: TextStyle(color: Colors.black, fontSize: 20), 74 | ), 75 | ) 76 | ], 77 | ), 78 | new Column( 79 | mainAxisAlignment: MainAxisAlignment.center, 80 | children: [ 81 | new Image.asset( 82 | 'assets/images/logo.jpg', 83 | width: animation.value<=0?15:animation.value * 150, 84 | height: animation.value<=0?15:animation.value * 150, 85 | ), 86 | ], 87 | ), 88 | ], 89 | ), 90 | ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/pages/widgets/widgets_page.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 flutter widgets 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2020-04-04 6 | * 7 | */ 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_study_app/common/model/func_model.dart'; 10 | 11 | class WidgetsPage extends StatefulWidget { 12 | const WidgetsPage({Key key}) : super(key: key); 13 | 14 | @override 15 | _WidgetsPageState createState() => _WidgetsPageState(); 16 | } 17 | 18 | class _WidgetsPageState extends State { 19 | 20 | List itemTitles = [ 21 | // FuncModel(name: 'sqflite数据库', routePath: Routes.sqflitePage), 22 | ]; 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return Scaffold( 27 | appBar: AppBar( 28 | centerTitle: true, 29 | title: Text("常用Widgets"), 30 | ), 31 | body: Container( 32 | child: Text("I am Flutter Widgets"), 33 | ), 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/provider/color_filtered_model.dart: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @描述 创建provider 数据模型,颜色过滤,变灰 4 | * 5 | * 这里的 Model 实际上就是我们的状态, 6 | * 它不仅储存了我们的数据模型,而且还包含了更改数据的方法,并暴露出它想要暴露出的数据 7 | * 8 | * @author chessluo 9 | * @email superluo666@gmail.com 10 | * @date 2019/4/4 11 | * 12 | */ 13 | 14 | import 'package:flutter/material.dart'; 15 | 16 | 17 | class ColorFilteredProvider with ChangeNotifier { 18 | 19 | Color _colorFiltered = Colors.transparent;//默认透明 20 | 21 | get currentColor => _colorFiltered; //获取当前过滤后颜色 22 | 23 | ///设置过滤后的颜色 24 | void currColorFiltered(Color color) { 25 | _colorFiltered = color; 26 | notifyListeners(); 27 | } 28 | } -------------------------------------------------------------------------------- /lib/res/colors.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttertoast/fluttertoast.dart'; 4 | import 'package:shared_preferences/shared_preferences.dart'; 5 | 6 | class AppColors { 7 | static const Color primaryColor = Color(0xff7C46B3); 8 | static const Color toastBlackBgColor = Color(0xA6000000);//可设置透明度 A6 9 | static const Color transparent = Color(0x00000000); 10 | 11 | static const Color appBlueColor = Color(0xff46B6FF); 12 | static const Color appBlue1Color = Color(0xff1048FF); 13 | 14 | static const Color grayf5f5f5 = Color(0xffd9d9d9); 15 | 16 | 17 | 18 | 19 | ///输入#000000颜色字符串,获取颜色对象Color 20 | static Color getColor(String colorStr){ 21 | if(colorStr!=null){ 22 | if(colorStr.substring(0,1)!="#"){ 23 | return primaryColor; 24 | } 25 | String substring = colorStr.substring(1,colorStr.length); 26 | return Color(int.parse('0xff'+substring)); 27 | } 28 | return primaryColor; 29 | } 30 | 31 | 32 | 33 | } -------------------------------------------------------------------------------- /lib/res/string_zh.dart: -------------------------------------------------------------------------------- 1 | class StringZh { 2 | static const String dart = "Dart基础"; 3 | static const String otherDemo = "Other Demo"; 4 | static const String appDesc = " Flutter 是 Google 开源的 UI 工具包,能够帮助开发者通过一套代码库高效构建多平台精美应用," 5 | "并且还支持移动、Web、桌面和嵌入式平台。\n\n" 6 | " 随着Flutter被越来越多的知名公司应用在自己的商业APP中," 7 | "Flutter这门新技术也逐渐进入了移动开发者的视野," 8 | "🔥勤能补拙,我希望能利用业余时间去学习及总结一些有关flutter的知识并运用到项目中去," 9 | "Come on!!!"; 10 | static const appAddress = "https://github.com/ChessLuo/flutter_study_app"; 11 | 12 | } -------------------------------------------------------------------------------- /lib/routers/application.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | 3 | 4 | class Application { 5 | static FluroRouter router; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /lib/routers/router_handler.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluro/fluro.dart'; 3 | import 'package:flutter_study_app/pages/anim/anim_page.dart'; 4 | import 'package:flutter_study_app/pages/anim/basis_canvas_page.dart'; 5 | import 'package:flutter_study_app/pages/cache/local_cache_page.dart'; 6 | import 'package:flutter_study_app/pages/dart/dart_page.dart'; 7 | import 'package:flutter_study_app/pages/main/about_page.dart'; 8 | import 'package:flutter_study_app/pages/main/main_page.dart'; 9 | import 'package:flutter_study_app/pages/other/demo/event_bus_demo.dart'; 10 | import 'package:flutter_study_app/pages/other/demo/file_zip_demo.dart'; 11 | import 'package:flutter_study_app/pages/channel/flutter_channel_demo.dart'; 12 | import 'package:flutter_study_app/pages/other/demo/flutter_webview_demo.dart'; 13 | import 'package:flutter_study_app/pages/cache/demo/preferences_demo.dart'; 14 | import 'package:flutter_study_app/pages/cache/demo/sqflite_demo.dart'; 15 | import 'package:flutter_study_app/pages/other/demo/url_launcher_demo.dart'; 16 | import 'package:flutter_study_app/pages/other/demo/webview_plugin_demo.dart'; 17 | import 'package:flutter_study_app/pages/other/other_page.dart'; 18 | import 'package:flutter_study_app/pages/state/provider_demo/provider_demo.dart'; 19 | import 'package:flutter_study_app/pages/state/state_page.dart'; 20 | import 'package:flutter_study_app/pages/transition_page.dart'; 21 | import 'package:flutter_study_app/pages/widgets/widgets_page.dart'; 22 | 23 | ///欢迎页面 24 | var transitionHandler = Handler( 25 | handlerFunc: (BuildContext context, Map> params) { 26 | return TransitionPage(); 27 | }, 28 | ); 29 | 30 | /// app的主页 31 | var mainHandler = Handler( 32 | handlerFunc: (BuildContext context, Map> params) { 33 | return MainPage(); 34 | }, 35 | ); 36 | 37 | /// flutter dart 38 | var dartHandler = Handler( 39 | handlerFunc: (BuildContext context, Map> params) { 40 | return DartPage(); 41 | }, 42 | ); 43 | 44 | /// flutter widgets 45 | var widgetsHandler = Handler( 46 | handlerFunc: (BuildContext context, Map> params) { 47 | return WidgetsPage(); 48 | }, 49 | ); 50 | 51 | /// flutter 动画 52 | var animHandler = Handler( 53 | handlerFunc: (BuildContext context, Map> params) { 54 | return AnimDemoList(); 55 | }, 56 | ); 57 | 58 | var customPaintHandler = Handler( 59 | handlerFunc: (BuildContext context, Map> params) { 60 | return CustomPaintPage(); 61 | }, 62 | ); 63 | 64 | 65 | ///provider状态管理 66 | var stateHandler = Handler( 67 | handlerFunc: (BuildContext context, Map> params) { 68 | return StateDemoList(); 69 | }); 70 | var providerHandler = Handler( 71 | handlerFunc: (BuildContext context, Map> params) { 72 | return ProviderDemoPage(); 73 | }); 74 | 75 | /// flutter数据存储 76 | var localCacheHandler = Handler( 77 | handlerFunc: (BuildContext context, Map> params) { 78 | return LocalCachePage(); 79 | }, 80 | ); 81 | 82 | var sqfliteHandler = Handler( 83 | handlerFunc: (BuildContext context, Map> params) { 84 | return SqflitePage(); 85 | }, 86 | ); 87 | 88 | var spHandler = Handler( 89 | handlerFunc: (BuildContext context, Map> params) { 90 | return PreferencesDemo(); 91 | }); 92 | 93 | /// 其他demo列表页 94 | var otherListHandler = Handler( 95 | handlerFunc: (BuildContext context, Map> params) { 96 | return OtherDemoList(); 97 | }, 98 | ); 99 | 100 | /// eventbus事件总线 101 | var eventBusHandler = Handler( 102 | handlerFunc: (BuildContext context, Map> params) { 103 | return EventBusPage(); 104 | }, 105 | ); 106 | 107 | /// 文件解压缩 108 | var fileZipHandler = Handler( 109 | handlerFunc: (BuildContext context, Map> params) { 110 | return FileZipDemo(); 111 | }, 112 | ); 113 | 114 | ///WebView(flutter_webview_plugin) 115 | var webViewPlginHandler = Handler( 116 | handlerFunc: (BuildContext context, Map> params) { 117 | String url = params['url']?.first; 118 | String title = params['title']?.first; 119 | return WebViewPlgin( 120 | url: url, 121 | title: title, 122 | ); 123 | }); 124 | 125 | ///WebView(flutter官方插件) 126 | var flutterWebViewHandler = Handler( 127 | handlerFunc: (BuildContext context, Map> params) { 128 | String url = params['url']?.first; 129 | String title = params['title']?.first; 130 | return FlutterWebView( 131 | url: url, 132 | barTitle: title, 133 | ); 134 | }); 135 | 136 | ///flutter channel 137 | var channelHandler = Handler( 138 | handlerFunc: (BuildContext context, Map> params) { 139 | return ChannelDemo(); 140 | }); 141 | 142 | ///urlLauncher 143 | var urlLauncherHandler = Handler( 144 | handlerFunc: (BuildContext context, Map> params) { 145 | return UrlLauncherDemo(); 146 | }); 147 | 148 | ///关于 149 | var aboutHandler = Handler( 150 | handlerFunc: (BuildContext context, Map> params) { 151 | return AboutPage(); 152 | }); 153 | -------------------------------------------------------------------------------- /lib/routers/routers.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import './router_handler.dart'; 5 | 6 | class Routes { 7 | static String root = "/"; 8 | static String transitionPage = "/transition"; 9 | static String mainPage = "/main"; 10 | static String aboutPage = "/about"; 11 | 12 | static String dartPage = "/dart"; 13 | static String widgetsPage = "/widgets"; 14 | 15 | ///canvas与动画 16 | static String animPage = "/anim"; 17 | static String customPaintPage = "/customPaint"; 18 | 19 | ///状态管理 20 | static String statePage = "/state"; 21 | static String providerPage = "/provider"; 22 | 23 | ///数据库存储 24 | static String localCachePage = "/localCache"; 25 | static String sqflitePage = "/sqflite"; 26 | static String sharedPreferences = "/sharedPreferences"; 27 | 28 | ///其他 29 | static String otherListPage = "/other"; 30 | static String eventBusPage = "/eventBus"; 31 | static String fileZipPage = "/fileZip"; 32 | static String webViewPlginPage = "/webViewPlgin"; 33 | static String flutterWebViewPage = "/flutterWebView"; 34 | static String flutterChannel = "/flutterChannel"; 35 | static String urlLauncher = "/urlLauncher"; 36 | 37 | static void configureRoutes(FluroRouter router) { 38 | router.notFoundHandler = Handler( 39 | handlerFunc: 40 | (BuildContext context, Map> params) {}); 41 | 42 | router.define(transitionPage, handler: transitionHandler); 43 | router.define(mainPage, handler: mainHandler); 44 | router.define(aboutPage, handler: aboutHandler); 45 | 46 | router.define(dartPage, handler: dartHandler); 47 | router.define(widgetsPage, handler: widgetsHandler); 48 | 49 | router.define(animPage, handler: animHandler); 50 | router.define(customPaintPage, handler: customPaintHandler); 51 | 52 | router.define(statePage, handler: stateHandler); 53 | router.define(providerPage, handler: providerHandler); 54 | 55 | router.define(localCachePage, handler: localCacheHandler); 56 | router.define(sqflitePage, handler: sqfliteHandler); 57 | router.define(sharedPreferences, handler: spHandler); 58 | 59 | router.define(otherListPage, handler: otherListHandler); 60 | router.define(eventBusPage, handler: eventBusHandler); 61 | router.define(fileZipPage, handler: fileZipHandler); 62 | router.define(webViewPlginPage, handler: webViewPlginHandler); 63 | router.define(flutterWebViewPage, handler: flutterWebViewHandler); 64 | router.define(flutterChannel, handler: channelHandler); 65 | router.define(urlLauncher, handler: urlLauncherHandler); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/utils/object_util.dart: -------------------------------------------------------------------------------- 1 | ///比较、判空 2 | class ObjectUtil { 3 | /// Returns true if the string is null or 0-length. 4 | static bool isEmptyString(String str) { 5 | return str == null || str.isEmpty; 6 | } 7 | 8 | /// Returns true if the list is null or 0-length. 9 | static bool isEmptyList(List list) { 10 | return list == null || list.isEmpty; 11 | } 12 | 13 | /// Returns true if there is no key/value pair in the map. 14 | static bool isEmptyMap(Map map) { 15 | return map == null || map.isEmpty; 16 | } 17 | 18 | /// Returns true String or List or Map is empty. 19 | static bool isEmpty(Object object) { 20 | if (object == null) return true; 21 | if (object is String && object.isEmpty) { 22 | return true; 23 | } else if (object is List && object.isEmpty) { 24 | return true; 25 | } else if (object is Map && object.isEmpty) { 26 | return true; 27 | } 28 | return false; 29 | } 30 | 31 | /// Returns true String or List or Map is not empty. 32 | static bool isNotEmpty(Object object) { 33 | return !isEmpty(object); 34 | } 35 | 36 | /// Returns true Two List Is Equal. 37 | static bool twoListIsEqual(List listA, List listB) { 38 | if (listA == listB) return true; 39 | if (listA == null || listB == null) return false; 40 | int length = listA.length; 41 | if (length != listB.length) return false; 42 | for (int i = 0; i < length; i++) { 43 | if (!listA.contains(listB[i])) { 44 | return false; 45 | } 46 | } 47 | return true; 48 | } 49 | 50 | /// get length. 51 | static int getLength(Object value) { 52 | if (value == null) return 0; 53 | if (value is String) { 54 | return value.length; 55 | } else if (value is List) { 56 | return value.length; 57 | } else if (value is Map) { 58 | return value.length; 59 | } else { 60 | return 0; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/utils/toast_util.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @描述 toast工具类 3 | * @author chessluo 4 | * @email superluo666@gmail.com 5 | * @date 2020-04-04 6 | * 7 | */ 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_study_app/res/colors.dart'; 10 | import 'package:fluttertoast/fluttertoast.dart'; 11 | 12 | class ToastUtil { 13 | ///toast可设置背景颜色默认背景黑色半透明,其他默认 14 | static void showToast(String msg, 15 | {Color color = AppColors.toastBlackBgColor, 16 | int timeInSecForIos = 1, 17 | Toast toastLength = Toast.LENGTH_SHORT}) { 18 | Fluttertoast.showToast( 19 | msg: "$msg", 20 | toastLength: toastLength, 21 | timeInSecForIosWeb: timeInSecForIos, 22 | backgroundColor: color); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: "direct main" 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "3.1.2" 11 | async: 12 | dependency: transitive 13 | description: 14 | name: async 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.6.1" 18 | boolean_selector: 19 | dependency: transitive 20 | description: 21 | name: boolean_selector 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.1.0" 25 | characters: 26 | dependency: transitive 27 | description: 28 | name: characters 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.1.0" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.2.0" 39 | clock: 40 | dependency: transitive 41 | description: 42 | name: clock 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.1.0" 46 | collection: 47 | dependency: transitive 48 | description: 49 | name: collection 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.15.0" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "3.0.1" 60 | cupertino_icons: 61 | dependency: "direct main" 62 | description: 63 | name: cupertino_icons 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.0.3" 67 | event_bus: 68 | dependency: "direct main" 69 | description: 70 | name: event_bus 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "2.0.0" 74 | fake_async: 75 | dependency: transitive 76 | description: 77 | name: fake_async 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.2.0" 81 | ffi: 82 | dependency: transitive 83 | description: 84 | name: ffi 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "1.1.2" 88 | file: 89 | dependency: transitive 90 | description: 91 | name: file 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "6.1.2" 95 | fluro: 96 | dependency: "direct main" 97 | description: 98 | name: fluro 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "2.0.3" 102 | flutter: 103 | dependency: "direct main" 104 | description: flutter 105 | source: sdk 106 | version: "0.0.0" 107 | flutter_test: 108 | dependency: "direct dev" 109 | description: flutter 110 | source: sdk 111 | version: "0.0.0" 112 | flutter_web_plugins: 113 | dependency: transitive 114 | description: flutter 115 | source: sdk 116 | version: "0.0.0" 117 | flutter_webview_plugin: 118 | dependency: "direct main" 119 | description: 120 | name: flutter_webview_plugin 121 | url: "https://pub.dartlang.org" 122 | source: hosted 123 | version: "0.4.0" 124 | fluttertoast: 125 | dependency: "direct main" 126 | description: 127 | name: fluttertoast 128 | url: "https://pub.dartlang.org" 129 | source: hosted 130 | version: "8.0.7" 131 | js: 132 | dependency: transitive 133 | description: 134 | name: js 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "0.6.3" 138 | matcher: 139 | dependency: transitive 140 | description: 141 | name: matcher 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "0.12.10" 145 | meta: 146 | dependency: transitive 147 | description: 148 | name: meta 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "1.3.0" 152 | mime: 153 | dependency: transitive 154 | description: 155 | name: mime 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "1.0.0" 159 | nested: 160 | dependency: transitive 161 | description: 162 | name: nested 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "1.0.0" 166 | path: 167 | dependency: transitive 168 | description: 169 | name: path 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "1.8.0" 173 | path_provider: 174 | dependency: "direct main" 175 | description: 176 | name: path_provider 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "2.0.2" 180 | path_provider_linux: 181 | dependency: transitive 182 | description: 183 | name: path_provider_linux 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "2.0.0" 187 | path_provider_macos: 188 | dependency: transitive 189 | description: 190 | name: path_provider_macos 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "2.0.0" 194 | path_provider_platform_interface: 195 | dependency: transitive 196 | description: 197 | name: path_provider_platform_interface 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "2.0.1" 201 | path_provider_windows: 202 | dependency: transitive 203 | description: 204 | name: path_provider_windows 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "2.0.1" 208 | permission_handler: 209 | dependency: "direct main" 210 | description: 211 | name: permission_handler 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "8.1.2" 215 | permission_handler_platform_interface: 216 | dependency: transitive 217 | description: 218 | name: permission_handler_platform_interface 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "3.6.0" 222 | platform: 223 | dependency: transitive 224 | description: 225 | name: platform 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "3.0.0" 229 | plugin_platform_interface: 230 | dependency: transitive 231 | description: 232 | name: plugin_platform_interface 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "2.0.1" 236 | process: 237 | dependency: transitive 238 | description: 239 | name: process 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "4.2.1" 243 | provider: 244 | dependency: "direct main" 245 | description: 246 | name: provider 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "5.0.0" 250 | share: 251 | dependency: "direct main" 252 | description: 253 | name: share 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "2.0.4" 257 | shared_preferences: 258 | dependency: "direct main" 259 | description: 260 | name: shared_preferences 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "2.0.6" 264 | shared_preferences_linux: 265 | dependency: transitive 266 | description: 267 | name: shared_preferences_linux 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "2.0.0" 271 | shared_preferences_macos: 272 | dependency: transitive 273 | description: 274 | name: shared_preferences_macos 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "2.0.0" 278 | shared_preferences_platform_interface: 279 | dependency: transitive 280 | description: 281 | name: shared_preferences_platform_interface 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "2.0.0" 285 | shared_preferences_web: 286 | dependency: transitive 287 | description: 288 | name: shared_preferences_web 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "2.0.0" 292 | shared_preferences_windows: 293 | dependency: transitive 294 | description: 295 | name: shared_preferences_windows 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "2.0.0" 299 | sky_engine: 300 | dependency: transitive 301 | description: flutter 302 | source: sdk 303 | version: "0.0.99" 304 | source_span: 305 | dependency: transitive 306 | description: 307 | name: source_span 308 | url: "https://pub.dartlang.org" 309 | source: hosted 310 | version: "1.8.1" 311 | sqflite: 312 | dependency: "direct main" 313 | description: 314 | name: sqflite 315 | url: "https://pub.dartlang.org" 316 | source: hosted 317 | version: "2.0.0+3" 318 | sqflite_common: 319 | dependency: transitive 320 | description: 321 | name: sqflite_common 322 | url: "https://pub.dartlang.org" 323 | source: hosted 324 | version: "2.0.0+2" 325 | stack_trace: 326 | dependency: transitive 327 | description: 328 | name: stack_trace 329 | url: "https://pub.dartlang.org" 330 | source: hosted 331 | version: "1.10.0" 332 | stream_channel: 333 | dependency: transitive 334 | description: 335 | name: stream_channel 336 | url: "https://pub.dartlang.org" 337 | source: hosted 338 | version: "2.1.0" 339 | string_scanner: 340 | dependency: transitive 341 | description: 342 | name: string_scanner 343 | url: "https://pub.dartlang.org" 344 | source: hosted 345 | version: "1.1.0" 346 | synchronized: 347 | dependency: transitive 348 | description: 349 | name: synchronized 350 | url: "https://pub.dartlang.org" 351 | source: hosted 352 | version: "3.0.0" 353 | term_glyph: 354 | dependency: transitive 355 | description: 356 | name: term_glyph 357 | url: "https://pub.dartlang.org" 358 | source: hosted 359 | version: "1.2.0" 360 | test_api: 361 | dependency: transitive 362 | description: 363 | name: test_api 364 | url: "https://pub.dartlang.org" 365 | source: hosted 366 | version: "0.3.0" 367 | typed_data: 368 | dependency: transitive 369 | description: 370 | name: typed_data 371 | url: "https://pub.dartlang.org" 372 | source: hosted 373 | version: "1.3.0" 374 | url_launcher: 375 | dependency: "direct main" 376 | description: 377 | name: url_launcher 378 | url: "https://pub.dartlang.org" 379 | source: hosted 380 | version: "6.0.9" 381 | url_launcher_linux: 382 | dependency: transitive 383 | description: 384 | name: url_launcher_linux 385 | url: "https://pub.dartlang.org" 386 | source: hosted 387 | version: "2.0.0" 388 | url_launcher_macos: 389 | dependency: transitive 390 | description: 391 | name: url_launcher_macos 392 | url: "https://pub.dartlang.org" 393 | source: hosted 394 | version: "2.0.0" 395 | url_launcher_platform_interface: 396 | dependency: transitive 397 | description: 398 | name: url_launcher_platform_interface 399 | url: "https://pub.dartlang.org" 400 | source: hosted 401 | version: "2.0.4" 402 | url_launcher_web: 403 | dependency: transitive 404 | description: 405 | name: url_launcher_web 406 | url: "https://pub.dartlang.org" 407 | source: hosted 408 | version: "2.0.1" 409 | url_launcher_windows: 410 | dependency: transitive 411 | description: 412 | name: url_launcher_windows 413 | url: "https://pub.dartlang.org" 414 | source: hosted 415 | version: "2.0.0" 416 | vector_math: 417 | dependency: transitive 418 | description: 419 | name: vector_math 420 | url: "https://pub.dartlang.org" 421 | source: hosted 422 | version: "2.1.0" 423 | webview_flutter: 424 | dependency: "direct main" 425 | description: 426 | name: webview_flutter 427 | url: "https://pub.dartlang.org" 428 | source: hosted 429 | version: "2.0.9" 430 | win32: 431 | dependency: transitive 432 | description: 433 | name: win32 434 | url: "https://pub.dartlang.org" 435 | source: hosted 436 | version: "2.2.5" 437 | xdg_directories: 438 | dependency: transitive 439 | description: 440 | name: xdg_directories 441 | url: "https://pub.dartlang.org" 442 | source: hosted 443 | version: "0.2.0" 444 | sdks: 445 | dart: ">=2.13.0 <3.0.0" 446 | flutter: ">=2.0.0" 447 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_study_app 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 | 16 | environment: 17 | sdk: ">=2.10.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^1.0.3 26 | 27 | sqflite: ^2.0.0+3 #数据库 28 | fluttertoast: ^8.0.7 #toast提示 29 | event_bus: ^2.0.0 #eventbus 30 | shared_preferences: ^2.0.6 #sp 31 | path_provider: ^2.0.2 #文件路径管理 32 | archive: ^3.1.2 #解/压缩 33 | permission_handler: ^8.1.2 #permission 34 | flutter_webview_plugin: ^0.4.0 35 | webview_flutter: ^2.0.9 #flutter官方webview 36 | provider: ^5.0.0 #状态管理 37 | fluro: ^2.0.3 #路由管理 38 | url_launcher: ^6.0.9 #url 跳转 39 | share: ^2.0.4 #分享 40 | 41 | dev_dependencies: 42 | flutter_test: 43 | sdk: flutter 44 | 45 | 46 | # For information on the generic Dart part of this file, see the 47 | # following page: https://www.dartlang.org/tools/pub/pubspec 48 | 49 | # The following section is specific to Flutter. 50 | flutter: 51 | 52 | # The following line ensures that the Material Icons font is 53 | # included with your application, so that you can use the icons in 54 | # the material Icons class. 55 | uses-material-design: true 56 | 57 | # To add assets to your application, add an assets section, like this: 58 | # assets: 59 | # - images/a_dot_burr.jpeg 60 | # - images/a_dot_ham.jpeg 61 | assets: 62 | - assets/images/ 63 | 64 | # An image asset can refer to one or more resolution-specific "variants", see 65 | # https://flutter.io/assets-and-images/#resolution-aware. 66 | 67 | # For details regarding adding assets from package dependencies, see 68 | # https://flutter.io/assets-and-images/#from-packages 69 | 70 | # To add custom fonts to your application, add a fonts section here, 71 | # in this "flutter" section. Each entry in this list should have a 72 | # "family" key with the font family name, and a "fonts" key with a 73 | # list giving the asset and other descriptors for the font. For 74 | # example: 75 | # fonts: 76 | # - family: Schyler 77 | # fonts: 78 | # - asset: fonts/Schyler-Regular.ttf 79 | # - asset: fonts/Schyler-Italic.ttf 80 | # style: italic 81 | # - family: Trajan Pro 82 | # fonts: 83 | # - asset: fonts/TrajanPro.ttf 84 | # - asset: fonts/TrajanPro_Bold.ttf 85 | # weight: 700 86 | # 87 | # For details regarding fonts from package dependencies, 88 | # see https://flutter.io/custom-fonts/#from-packages 89 | -------------------------------------------------------------------------------- /screenshots/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/about.png -------------------------------------------------------------------------------- /screenshots/channel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/channel.gif -------------------------------------------------------------------------------- /screenshots/drawer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/drawer.png -------------------------------------------------------------------------------- /screenshots/gfone.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/gfone.gif -------------------------------------------------------------------------------- /screenshots/gray.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/gray.gif -------------------------------------------------------------------------------- /screenshots/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/main.png -------------------------------------------------------------------------------- /screenshots/myQrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/myQrcode.jpg -------------------------------------------------------------------------------- /screenshots/other.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/other.png -------------------------------------------------------------------------------- /screenshots/router.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/router.gif -------------------------------------------------------------------------------- /screenshots/shared_preferences.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/shared_preferences.gif -------------------------------------------------------------------------------- /screenshots/sqflite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/sqflite.png -------------------------------------------------------------------------------- /screenshots/url_launcher.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/url_launcher.gif -------------------------------------------------------------------------------- /screenshots/webview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/webview.gif -------------------------------------------------------------------------------- /screenshots/zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChessLuo/flutter_study_app/db74f8c082b9597a0b74cf4135807201eeebe18a/screenshots/zip.png -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_study_app/fl_app.dart'; 10 | import 'package:flutter_test/flutter_test.dart'; 11 | 12 | void main() { 13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 14 | // Build our app and trigger a frame. 15 | await tester.pumpWidget(MyApp()); 16 | 17 | // Verify that our counter starts at 0. 18 | expect(find.text('0'), findsOneWidget); 19 | expect(find.text('1'), findsNothing); 20 | 21 | // Tap the '+' icon and trigger a frame. 22 | await tester.tap(find.byIcon(Icons.add)); 23 | await tester.pump(); 24 | 25 | // Verify that our counter has incremented. 26 | expect(find.text('0'), findsNothing); 27 | expect(find.text('1'), findsOneWidget); 28 | }); 29 | } 30 | --------------------------------------------------------------------------------