├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── build.gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── weilu │ │ └── flutter │ │ └── flutter_2d_amap │ │ ├── AMap2DDelegate.java │ │ ├── AMap2DFactory.java │ │ ├── AMap2DView.java │ │ └── Flutter2dAmapPlugin.java │ └── res │ └── drawable-xxxhdpi │ └── yd.png ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ ├── key.properties │ │ ├── src │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── weilu │ │ │ │ │ │ └── flutter │ │ │ │ │ │ └── flutter_2d_amap_example │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res │ │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ │ └── xml │ │ │ │ │ └── network_security_config.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── test.jks │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ ├── Flutter.podspec │ │ └── Release.xcconfig │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── 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 │ └── main.dart ├── pubspec.lock ├── pubspec.yaml ├── test │ └── widget_test.dart └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ └── Icon-512.png │ ├── index.html │ └── manifest.json ├── flutter_2d_amap.iml ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── Flutter2dAmapPlugin.h │ ├── Flutter2dAmapPlugin.m │ ├── FlutterAMap2D.h │ └── FlutterAMap2D.m └── flutter_2d_amap.podspec ├── lib ├── flutter_2d_amap.dart └── src │ ├── amap_2d_view.dart │ ├── amap_2d_view_state.dart │ ├── interface │ └── amap_2d_controller.dart │ ├── mobile │ ├── amap_2d_controller.dart │ └── amap_2d_view_state.dart │ ├── poi_search_model.dart │ └── web │ ├── amap_2d_controller.dart │ ├── amap_2d_view_state.dart │ ├── amapjs.dart │ ├── html_element_view.dart │ └── loaderjs.dart ├── preview └── Screenshot_1.jpg ├── pubspec.lock ├── pubspec.yaml └── test └── flutter_2d_amap_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | example/ios/.symlinks 9 | .idea/ -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.2.0 2 | 3 | * Migrate to null safety. 4 | 5 | ## 0.1.0 (48f8e937) 6 | 7 | * 支持Web。(基本功能使用没问题,部分地图显示有问题。) 8 | 9 | ## 0.0.4 10 | 11 | * POI搜索支持指定城市,默认全国。 12 | * 地图点击替换为POI周边查询接口。 13 | 14 | ## 0.0.3 15 | 16 | * 点击地图选点时,去除地图缩放。 17 | * 更新Android依赖至最新: 18 | 19 | ```groovy 20 | api 'com.amap.api:map2d:6.0.0' 21 | api 'com.amap.api:search:7.1.0' 22 | api 'com.amap.api:location:4.8.0' 23 | ``` 24 | 25 | ## 0.0.2 26 | 27 | * 支持Flutter 1.12版本新的android插件api 28 | * Android权限申请优化 29 | 30 | ## 0.0.1 31 | 32 | * 处理地图所需权限申请 33 | * 定位并自动移动地图至当前位置 34 | * 默认获取POI数据并返回 35 | * 支持传入经纬度来移动地图 36 | * 支持搜索POI 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_2d_amap 2 | 3 | 高德2D地图插件 4 | 5 | 本插件主要服务于 [flutter_deer](https://github.com/simplezhli/flutter_deer)。仅保持现有功能,没有的功能可自行拓展。 6 | 7 | ## 效果展示 8 | 9 | 10 | 11 | ## 实现功能包括 12 | 13 | * 支持Android、iOS、Web([玩玩Flutter Web —— 实现高德地图插件](https://weilu.blog.csdn.net/article/details/106465792)) 14 | * 处理地图所需权限申请 15 | * 定位并自动移动地图至当前位置 16 | * 默认获取POI数据并返回 17 | * 支持传入经纬度来移动地图 18 | * 支持搜索POI 19 | 20 | ## 已知问题 21 | 22 | - https://github.com/simplezhli/flutter_2d_amap/issues/14 23 | 24 | ## 使用方式 25 | 26 | pubspec.yaml 添加: 27 | 28 | ``` 29 | flutter_2d_amap: 30 | git: 31 | url: https://github.com/simplezhli/flutter_2d_amap.git 32 | ``` 33 | 34 | 使用前同意隐私政策: 35 | 36 | ```dart 37 | Flutter2dAMap.updatePrivacy(true); 38 | ``` 39 | 40 | 使用: 41 | 42 | ```dart 43 | import 'package:flutter_2d_amap/flutter_2d_amap.dart'; 44 | 45 | AMap2DView( 46 | onPoiSearched: (result) { 47 | 48 | }, 49 | onAMap2DViewCreated: (controller) { 50 | 51 | }, 52 | ) 53 | 54 | ``` 55 | 56 | ### Android 57 | 58 | AndroidManifest.xml 中添加: 59 | 60 | ```java 61 | 62 | 65 | 66 | ``` 67 | 68 | 如果你的`targetSdkVersion`为27以上,则需要做以下配置来支持http明文请求(具体可以看demo),否则会导致地图加载不出: 69 | 70 | AndroidManifest.xml 中添加: 71 | 72 | ```java 73 | 76 | 77 | ``` 78 | 79 | 在 res 下新增一个 xml 目录,然后创建一个名为:`network_security_config.xml` 文件: 80 | 81 | ```xml 82 | 83 | 84 | 85 | 86 | ``` 87 | 88 | ### iOS 89 | 90 | 使用前设置key: 91 | 92 | ```dart 93 | Flutter2dAMap.setApiKey(iOSKey: '配置你的key'); 94 | 95 | ``` 96 | 97 | 在info.plist中增加: 98 | 99 | ```xml 100 | NSLocationAlwaysAndWhenInUseUsageDescription 101 | 地图功能需要您的定位服务,否则无法使用,如果您需要使用后台定位功能请选择“始终允许”。 102 | 103 | NSLocationAlwaysUsageDescription 104 | 地图功能需要您的定位服务,否则无法使用。 105 | 106 | NSLocationWhenInUseUsageDescription 107 | 地图功能需要您的定位服务,否则无法使用。 108 | 109 | io.flutter.embedded_views_preview 110 | 111 | 112 | ``` 113 | 114 | ### Web 115 | 116 | `index.html`中添加(在`main.dart.js`之前): 117 | 118 | ```html 119 | 120 | ``` 121 | 122 | 使用前设置key: 123 | 124 | ```dart 125 | 126 | Flutter2dAMap.setApiKey(webKey: '配置你的key'); 127 | 128 | ``` 129 | 130 | ## License 131 | 132 | Copyright 2019 simplezhli 133 | 134 | Licensed under the Apache License, Version 2.0 (the "License"); 135 | you may not use this file except in compliance with the License. 136 | You may obtain a copy of the License at 137 | 138 | http://www.apache.org/licenses/LICENSE-2.0 139 | 140 | Unless required by applicable law or agreed to in writing, software 141 | distributed under the License is distributed on an "AS IS" BASIS, 142 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143 | See the License for the specific language governing permissions and 144 | limitations under the License. 145 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Specify analysis options. 2 | # 3 | # For a list of lints, see: http://dart-lang.github.io/linter/lints/ 4 | # See the configuration guide for more 5 | # https://github.com/dart-lang/sdk/tree/main/pkg/analyzer#configuring-the-analyzer 6 | # 7 | # There are other similar analysis options files in the flutter repos, 8 | # which should be kept in sync with this file: 9 | # 10 | # - analysis_options.yaml (this file) 11 | # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml 12 | # - https://github.com/flutter/engine/blob/master/analysis_options.yaml 13 | # - https://github.com/flutter/packages/blob/master/analysis_options.yaml 14 | # 15 | # This file contains the analysis options used for code in the flutter/flutter 16 | # repository. 17 | 18 | analyzer: 19 | language: 20 | strict-casts: true 21 | strict-raw-types: true 22 | errors: 23 | # allow self-reference to deprecated members (we do this because otherwise we have 24 | # to annotate every member in every test, assert, etc, when we deprecate something) 25 | deprecated_member_use_from_same_package: ignore 26 | # Turned off until null-safe rollout is complete. 27 | # unnecessary_null_comparison: ignore 28 | exclude: 29 | # the following two are relative to the stocks example and the flutter package respectively 30 | # see https://github.com/dart-lang/sdk/issues/28463 31 | - "lib/l10n/**" 32 | - "lib/generated/json/**" 33 | - "lib/widgets/bezier_chart/**" 34 | # - "test/**" 35 | - "test_driver/**" 36 | 37 | linter: 38 | rules: 39 | # This list is derived from the list of all available lints located at 40 | # https://github.com/dart-lang/linter/blob/master/example/all.yaml 41 | - always_declare_return_types 42 | - always_put_control_body_on_new_line 43 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 44 | - always_require_non_null_named_parameters 45 | # - always_specify_types 46 | # - always_use_package_imports # we do this commonly 47 | - annotate_overrides 48 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types 49 | - avoid_bool_literals_in_conditional_expressions 50 | # - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023 51 | # - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023 52 | # - avoid_classes_with_only_static_members 53 | - avoid_double_and_int_checks 54 | - avoid_dynamic_calls 55 | - avoid_empty_else 56 | - avoid_equals_and_hash_code_on_mutable_classes 57 | - avoid_escaping_inner_quotes 58 | - avoid_field_initializers_in_const_classes 59 | # - avoid_final_parameters # incompatible with prefer_final_parameters 60 | - avoid_function_literals_in_foreach_calls 61 | - avoid_implementing_value_types 62 | - avoid_init_to_null 63 | - avoid_js_rounded_ints 64 | # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to 65 | - avoid_null_checks_in_equality_operators 66 | # - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it 67 | - avoid_print 68 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 69 | - avoid_redundant_argument_values 70 | - avoid_relative_lib_imports 71 | - avoid_renaming_method_parameters 72 | - avoid_return_types_on_setters 73 | - avoid_returning_null 74 | - avoid_returning_null_for_future 75 | - avoid_returning_null_for_void 76 | # - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives 77 | - avoid_setters_without_getters 78 | - avoid_shadowing_type_parameters 79 | - avoid_single_cascade_in_expression_statements 80 | - avoid_slow_async_io 81 | - avoid_type_to_string 82 | - avoid_types_as_parameter_names 83 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types 84 | - avoid_unnecessary_containers 85 | - avoid_unused_constructor_parameters 86 | - avoid_void_async 87 | # - avoid_web_libraries_in_flutter # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere 88 | - await_only_futures 89 | - camel_case_extensions 90 | - camel_case_types 91 | - cancel_subscriptions 92 | # - cascade_invocations # doesn't match the typical style of this repo 93 | - cast_nullable_to_non_nullable 94 | # - close_sinks # not reliable enough 95 | # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 96 | - conditional_uri_does_not_exist 97 | # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 98 | - control_flow_in_finally 99 | - curly_braces_in_flow_control_structures 100 | - depend_on_referenced_packages 101 | - deprecated_consistency 102 | # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) 103 | - directives_ordering 104 | # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic 105 | - empty_catches 106 | - empty_constructor_bodies 107 | - empty_statements 108 | - eol_at_end_of_file 109 | - exhaustive_cases 110 | - file_names 111 | - flutter_style_todos 112 | - hash_and_equals 113 | - implementation_imports 114 | - implicit_call_tearoffs 115 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 116 | - iterable_contains_unrelated_type 117 | # - join_return_with_assignment # not required by flutter style 118 | - leading_newlines_in_multiline_strings 119 | - library_names 120 | - library_prefixes 121 | # - library_private_types_in_public_api 122 | # - lines_longer_than_80_chars # required by flutter style 123 | - list_remove_unrelated_type 124 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453 125 | - missing_whitespace_between_adjacent_strings 126 | - no_adjacent_strings_in_list 127 | - no_default_cases 128 | - no_duplicate_case_values 129 | - no_leading_underscores_for_library_prefixes 130 | - no_leading_underscores_for_local_identifiers 131 | - no_logic_in_create_state 132 | # - no_runtimeType_toString # ok in tests; we enable this only in packages/ 133 | - non_constant_identifier_names 134 | - noop_primitive_operations 135 | - null_check_on_nullable_type_parameter 136 | - null_closures 137 | # - omit_local_variable_types # opposite of always_specify_types 138 | # - one_member_abstracts # too many false positives 139 | - only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al 140 | - overridden_fields 141 | - package_api_docs 142 | - package_names 143 | - package_prefixed_library_names 144 | # - parameter_assignments # we do this commonly 145 | - prefer_adjacent_string_concatenation 146 | - prefer_asserts_in_initializer_lists 147 | # - prefer_asserts_with_message # not required by flutter style 148 | - prefer_collection_literals 149 | - prefer_conditional_assignment 150 | - prefer_const_constructors 151 | - prefer_const_constructors_in_immutables 152 | - prefer_const_declarations 153 | - prefer_const_literals_to_create_immutables 154 | # - prefer_constructors_over_static_methods # far too many false positives 155 | - prefer_contains 156 | # - prefer_double_quotes # opposite of prefer_single_quotes 157 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 158 | - prefer_final_fields 159 | - prefer_final_in_for_each 160 | - prefer_final_locals 161 | # - prefer_final_parameters # we should enable this one day when it can be auto-fixed (https://github.com/dart-lang/linter/issues/3104), see also parameter_assignments 162 | - prefer_for_elements_to_map_fromIterable 163 | - prefer_foreach 164 | - prefer_function_declarations_over_variables 165 | - prefer_generic_function_type_aliases 166 | - prefer_if_elements_to_conditional_expressions 167 | - prefer_if_null_operators 168 | - prefer_initializing_formals 169 | - prefer_inlined_adds 170 | # - prefer_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants 171 | - prefer_interpolation_to_compose_strings 172 | - prefer_is_empty 173 | - prefer_is_not_empty 174 | - prefer_is_not_operator 175 | - prefer_iterable_whereType 176 | # - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018 177 | # - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere 178 | # - prefer_relative_imports 179 | - prefer_single_quotes 180 | - prefer_spread_collections 181 | - prefer_typing_uninitialized_variables 182 | - prefer_void_to_null 183 | - provide_deprecation_message 184 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 185 | - recursive_getters 186 | # - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441 187 | - secure_pubspec_urls 188 | - sized_box_for_whitespace 189 | - sized_box_shrink_expand 190 | - slash_for_doc_comments 191 | - sort_child_properties_last 192 | - sort_constructors_first 193 | # - sort_pub_dependencies # prevents separating pinned transitive dependencies 194 | - sort_unnamed_constructors_first 195 | - test_types_in_equals 196 | - throw_in_finally 197 | - tighten_type_of_initializing_formals 198 | # - type_annotate_public_apis # subset of always_specify_types 199 | - type_init_formals 200 | # - unawaited_futures # too many false positives, especially with the way AnimationController works 201 | - unnecessary_await_in_return 202 | - unnecessary_brace_in_string_interps 203 | - unnecessary_const 204 | - unnecessary_constructor_name 205 | # - unnecessary_final # conflicts with prefer_final_locals 206 | - unnecessary_getters_setters 207 | # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 208 | - unnecessary_late 209 | - unnecessary_new 210 | - unnecessary_null_aware_assignments 211 | - unnecessary_null_aware_operator_on_extension_on_nullable 212 | - unnecessary_null_checks 213 | - unnecessary_null_in_if_null_operators 214 | - unnecessary_nullable_for_final_variable_declarations 215 | - unnecessary_overrides 216 | - unnecessary_parenthesis 217 | # - unnecessary_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint 218 | - unnecessary_statements 219 | - unnecessary_string_escapes 220 | - unnecessary_string_interpolations 221 | - unnecessary_this 222 | - unnecessary_to_list_in_spreads 223 | - unrelated_type_equality_checks 224 | - unsafe_html 225 | - use_build_context_synchronously 226 | - use_colored_box 227 | # - use_decorated_box # not yet tested 228 | - use_enums 229 | - use_full_hex_values_for_flutter_colors 230 | - use_function_type_syntax_for_parameters 231 | - use_if_null_to_convert_nulls_to_bools 232 | - use_is_even_rather_than_modulo 233 | - use_key_in_widget_constructors 234 | - use_late_for_private_fields_and_variables 235 | - use_named_constants 236 | - use_raw_strings 237 | - use_rethrow_when_possible 238 | - use_setters_to_change_properties 239 | - use_super_parameters 240 | # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 241 | - use_test_throws_matchers 242 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 243 | - valid_regexps 244 | - void_checks -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | /gradle 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.weilu.flutter.flutter_2d_amap' 2 | version '1.1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:7.2.2' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 33 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | targetSdkVersion 33 30 | } 31 | lintOptions { 32 | disable 'InvalidPackage' 33 | } 34 | namespace 'com.weilu.flutter.flutter_2d_amap' 35 | } 36 | 37 | dependencies { 38 | api 'com.amap.api:map2d:6.0.0' 39 | api 'com.amap.api:search:9.5.0' 40 | api 'com.amap.api:location:6.3.0' 41 | api 'androidx.core:core:1.0.2' 42 | } 43 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_2d_amap' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 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 | -------------------------------------------------------------------------------- /android/src/main/java/com/weilu/flutter/flutter_2d_amap/AMap2DDelegate.java: -------------------------------------------------------------------------------- 1 | package com.weilu.flutter.flutter_2d_amap; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.pm.PackageManager; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.core.app.ActivityCompat; 9 | import io.flutter.plugin.common.PluginRegistry; 10 | 11 | /** 12 | * @author weilu 13 | * 2019/6/28 0028 09:03. 14 | */ 15 | public class AMap2DDelegate implements PluginRegistry.RequestPermissionsResultListener { 16 | 17 | private static final int REQUEST_PERMISSION = 6666; 18 | 19 | private final String[] permission = { 20 | Manifest.permission.ACCESS_COARSE_LOCATION, 21 | Manifest.permission.ACCESS_FINE_LOCATION, 22 | Manifest.permission.READ_PHONE_STATE, 23 | }; 24 | 25 | interface PermissionManager { 26 | /** 27 | * 是否授予权限 28 | * @return 是否授予权限 29 | */ 30 | boolean isPermissionGranted(); 31 | 32 | /** 33 | * 请求权限 34 | */ 35 | void askForPermission(); 36 | } 37 | 38 | public interface RequestPermission { 39 | /** 40 | * 权限请求成功 41 | */ 42 | void onRequestPermissionSuccess(); 43 | /** 44 | * 权限请求失败 45 | */ 46 | void onRequestPermissionFailure(); 47 | } 48 | 49 | private RequestPermission mRequestPermission; 50 | 51 | private final PermissionManager permissionManager; 52 | 53 | AMap2DDelegate(final Activity activity) { 54 | 55 | permissionManager = new PermissionManager() { 56 | @Override 57 | public boolean isPermissionGranted() { 58 | for (String s : permission) { 59 | if (ActivityCompat.checkSelfPermission(activity, s) != PackageManager.PERMISSION_GRANTED) { 60 | return false; 61 | } 62 | } 63 | return true; 64 | } 65 | 66 | @Override 67 | public void askForPermission() { 68 | ActivityCompat.requestPermissions(activity, permission, REQUEST_PERMISSION); 69 | } 70 | }; 71 | } 72 | 73 | public void requestPermissions(@NonNull RequestPermission mRequestPermission) { 74 | this.mRequestPermission = mRequestPermission; 75 | if (!permissionManager.isPermissionGranted()) { 76 | permissionManager.askForPermission(); 77 | } else { 78 | mRequestPermission.onRequestPermissionSuccess(); 79 | } 80 | } 81 | 82 | @Override 83 | public boolean onRequestPermissionsResult(int requestCode, String[] strings, int[] ints) { 84 | if (requestCode == REQUEST_PERMISSION) { 85 | boolean permissionGranted = true; 86 | for (int i : ints) { 87 | if (i != PackageManager.PERMISSION_GRANTED) { 88 | permissionGranted = false; 89 | } 90 | } 91 | if (permissionGranted) { 92 | mRequestPermission.onRequestPermissionSuccess(); 93 | } else { 94 | mRequestPermission.onRequestPermissionFailure(); 95 | } 96 | return true; 97 | } else { 98 | return false; 99 | } 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /android/src/main/java/com/weilu/flutter/flutter_2d_amap/AMap2DFactory.java: -------------------------------------------------------------------------------- 1 | package com.weilu.flutter.flutter_2d_amap; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.Map; 6 | 7 | import io.flutter.plugin.common.BinaryMessenger; 8 | import io.flutter.plugin.common.StandardMessageCodec; 9 | import io.flutter.plugin.platform.PlatformView; 10 | import io.flutter.plugin.platform.PlatformViewFactory; 11 | 12 | /** 13 | * @author weilu 14 | * 2019/6/26 0026 10:16. 15 | */ 16 | public class AMap2DFactory extends PlatformViewFactory { 17 | 18 | private final BinaryMessenger messenger; 19 | private AMap2DDelegate delegate; 20 | private AMap2DView mAMap2DView; 21 | 22 | AMap2DFactory(BinaryMessenger messenger, AMap2DDelegate delegate) { 23 | super(StandardMessageCodec.INSTANCE); 24 | this.messenger = messenger; 25 | this.delegate = delegate; 26 | } 27 | 28 | void setDelegate(AMap2DDelegate delegate) { 29 | this.delegate = delegate; 30 | if (mAMap2DView != null) { 31 | mAMap2DView.setAMap2DDelegate(delegate); 32 | } 33 | } 34 | 35 | @Override 36 | public PlatformView create(Context context, int id, Object args) { 37 | Map params = (Map) args; 38 | mAMap2DView = new AMap2DView(context, messenger, id, params, delegate); 39 | return mAMap2DView; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/weilu/flutter/flutter_2d_amap/AMap2DView.java: -------------------------------------------------------------------------------- 1 | package com.weilu.flutter.flutter_2d_amap; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.os.Looper; 8 | import android.view.View; 9 | import android.widget.Toast; 10 | 11 | import androidx.annotation.NonNull; 12 | 13 | import com.amap.api.location.AMapLocation; 14 | import com.amap.api.location.AMapLocationClient; 15 | import com.amap.api.location.AMapLocationClientOption; 16 | import com.amap.api.location.AMapLocationListener; 17 | import com.amap.api.maps2d.AMap; 18 | import com.amap.api.maps2d.CameraUpdateFactory; 19 | import com.amap.api.maps2d.LocationSource; 20 | import com.amap.api.maps2d.MapView; 21 | import com.amap.api.maps2d.model.BitmapDescriptor; 22 | import com.amap.api.maps2d.model.BitmapDescriptorFactory; 23 | import com.amap.api.maps2d.model.LatLng; 24 | import com.amap.api.maps2d.model.Marker; 25 | import com.amap.api.maps2d.model.MarkerOptions; 26 | import com.amap.api.maps2d.model.MyLocationStyle; 27 | import com.amap.api.services.core.AMapException; 28 | import com.amap.api.services.core.LatLonPoint; 29 | import com.amap.api.services.core.PoiItem; 30 | import com.amap.api.services.poisearch.PoiResult; 31 | import com.amap.api.services.poisearch.PoiSearch; 32 | 33 | import java.util.HashMap; 34 | import java.util.List; 35 | import java.util.Map; 36 | 37 | import io.flutter.plugin.common.BinaryMessenger; 38 | import io.flutter.plugin.common.MethodCall; 39 | import io.flutter.plugin.common.MethodChannel; 40 | import io.flutter.plugin.platform.PlatformView; 41 | 42 | /** 43 | * @author weilu 44 | * 2019/6/26 0026 10:18. 45 | */ 46 | public class AMap2DView implements PlatformView, MethodChannel.MethodCallHandler, LocationSource, AMapLocationListener, 47 | AMap.OnMapClickListener, PoiSearch.OnPoiSearchListener { 48 | 49 | private static final String SEARCH_CONTENT = "010000|010100|020000|030000|040000|050000|050100|060000|060100|060200|060300|060400|070000|080000|080100|080300|080500|080600|090000|090100|090200|090300|100000|100100|110000|110100|120000|120200|120300|130000|140000|141200|150000|150100|150200|160000|160100|170000|170100|170200|180000|190000|200000"; 50 | 51 | private MapView mAMap2DView; 52 | private AMap aMap; 53 | private PoiSearch.Query query; 54 | private OnLocationChangedListener mListener; 55 | private AMapLocationClient mLocationClient; 56 | 57 | private final MethodChannel methodChannel; 58 | private final Handler platformThreadHandler; 59 | private Runnable postMessageRunnable; 60 | private final Context context; 61 | private String keyWord = ""; 62 | private boolean isPoiSearch; 63 | private static final String IS_POI_SEARCH = "isPoiSearch"; 64 | private String city = ""; 65 | 66 | AMap2DView(final Context context, BinaryMessenger messenger, int id, Map params, AMap2DDelegate delegate) { 67 | this.context = context; 68 | platformThreadHandler = new Handler(context.getMainLooper()); 69 | createMap(context); 70 | setAMap2DDelegate(delegate); 71 | mAMap2DView.onResume(); 72 | methodChannel = new MethodChannel(messenger, "plugins.weilu/flutter_2d_amap_" + id); 73 | methodChannel.setMethodCallHandler(this); 74 | 75 | if (params.containsKey(IS_POI_SEARCH)) { 76 | isPoiSearch = (boolean) params.get(IS_POI_SEARCH); 77 | } 78 | } 79 | 80 | void setAMap2DDelegate(AMap2DDelegate delegate) { 81 | if (delegate != null){ 82 | delegate.requestPermissions(new AMap2DDelegate.RequestPermission() { 83 | @Override 84 | public void onRequestPermissionSuccess() { 85 | setUpMap(); 86 | } 87 | 88 | @Override 89 | public void onRequestPermissionFailure() { 90 | Toast.makeText(context,"定位失败,请检查定位权限是否开启!", Toast.LENGTH_SHORT).show(); 91 | } 92 | }); 93 | } 94 | } 95 | 96 | private void createMap(Context context) { 97 | mAMap2DView = new MapView(context); 98 | mAMap2DView.onCreate(new Bundle()); 99 | aMap = mAMap2DView.getMap(); 100 | } 101 | 102 | private void setUpMap() { 103 | CameraUpdateFactory.zoomTo(32); 104 | aMap.setOnMapClickListener(this); 105 | // 设置定位监听 106 | aMap.setLocationSource(this); 107 | // 设置默认定位按钮是否显示 108 | aMap.getUiSettings().setMyLocationButtonEnabled(true); 109 | MyLocationStyle myLocationStyle = new MyLocationStyle(); 110 | myLocationStyle.strokeWidth(1f); 111 | myLocationStyle.strokeColor(Color.parseColor("#8052A3FF")); 112 | myLocationStyle.radiusFillColor(Color.parseColor("#3052A3FF")); 113 | myLocationStyle.showMyLocation(true); 114 | myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.yd)); 115 | myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE); 116 | aMap.setMyLocationStyle(myLocationStyle); 117 | // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false 118 | aMap.setMyLocationEnabled(true); 119 | } 120 | 121 | @Override 122 | public void onMethodCall(MethodCall methodCall, @NonNull MethodChannel.Result result) { 123 | String method = methodCall.method; 124 | Map request = (Map) methodCall.arguments; 125 | switch(method) { 126 | case "search": 127 | keyWord = (String) request.get("keyWord"); 128 | city = (String) request.get("city"); 129 | search(); 130 | break; 131 | case "move": 132 | move(toDouble((String) request.get("lat")), toDouble((String) request.get("lon"))); 133 | break; 134 | case "location": 135 | if (mLocationClient != null) { 136 | mLocationClient.startLocation(); 137 | } 138 | break; 139 | default: 140 | break; 141 | } 142 | } 143 | 144 | private double toDouble(String obj) { 145 | try { 146 | return Double.parseDouble(obj); 147 | } catch (Exception e) { 148 | e.fillInStackTrace(); 149 | } 150 | return 0D; 151 | } 152 | 153 | @Override 154 | public View getView() { 155 | return mAMap2DView; 156 | } 157 | 158 | @Override 159 | public void dispose() { 160 | mAMap2DView.onDestroy(); 161 | platformThreadHandler.removeCallbacks(postMessageRunnable); 162 | methodChannel.setMethodCallHandler(null); 163 | } 164 | 165 | @Override 166 | public void onLocationChanged(AMapLocation aMapLocation) { 167 | if (mListener != null && aMapLocation != null) { 168 | if (aMapLocation.getErrorCode() == 0) { 169 | // 显示系统小蓝点 170 | mListener.onLocationChanged(aMapLocation); 171 | aMap.moveCamera(CameraUpdateFactory.zoomTo(16)); 172 | search(aMapLocation.getLatitude(), aMapLocation.getLongitude()); 173 | } else { 174 | Toast.makeText(context,"定位失败,请检查GPS是否开启!", Toast.LENGTH_SHORT).show(); 175 | } 176 | if (mLocationClient != null) { 177 | mLocationClient.stopLocation(); 178 | } 179 | } 180 | } 181 | 182 | private void search() { 183 | if (!isPoiSearch) { 184 | return; 185 | } 186 | query = new PoiSearch.Query(keyWord, SEARCH_CONTENT, city); 187 | // 设置每页最多返回多少条poiitem 188 | query.setPageSize(50); 189 | query.setPageNum(0); 190 | try { 191 | PoiSearch poiSearch = new PoiSearch(context, query); 192 | poiSearch.setOnPoiSearchListener(this); 193 | poiSearch.searchPOIAsyn(); 194 | } catch (AMapException e) { 195 | e.printStackTrace(); 196 | } 197 | 198 | } 199 | 200 | private void move(double lat, double lon) { 201 | LatLng latLng = new LatLng(lat, lon); 202 | drawMarkers(latLng, BitmapDescriptorFactory.defaultMarker()); 203 | } 204 | 205 | private void search(double latitude, double longitude) { 206 | if (!isPoiSearch) { 207 | return; 208 | } 209 | query = new PoiSearch.Query("", SEARCH_CONTENT, ""); 210 | // 设置每页最多返回多少条poiitem 211 | query.setPageSize(50); 212 | query.setPageNum(0); 213 | 214 | try { 215 | PoiSearch poiSearch = new PoiSearch(context, query); 216 | poiSearch.setOnPoiSearchListener(this); 217 | LatLonPoint latLonPoint = new LatLonPoint(latitude, longitude); 218 | poiSearch.setBound(new PoiSearch.SearchBound(latLonPoint, 2000, true)); 219 | poiSearch.searchPOIAsyn(); 220 | } catch (AMapException e) { 221 | e.printStackTrace(); 222 | } 223 | } 224 | 225 | @Override 226 | public void onMapClick(LatLng latLng) { 227 | drawMarkers(latLng, BitmapDescriptorFactory.defaultMarker()); 228 | search(latLng.latitude, latLng.longitude); 229 | } 230 | 231 | private Marker mMarker; 232 | 233 | private void drawMarkers(LatLng latLng, BitmapDescriptor bitmapDescriptor) { 234 | aMap.animateCamera(CameraUpdateFactory.changeLatLng(new LatLng(latLng.latitude, latLng.longitude))); 235 | if (mMarker == null) { 236 | mMarker = aMap.addMarker(new MarkerOptions().position(latLng).icon(bitmapDescriptor).draggable(true)); 237 | } else { 238 | mMarker.setPosition(latLng); 239 | } 240 | } 241 | 242 | @Override 243 | public void activate(OnLocationChangedListener onLocationChangedListener) { 244 | mListener = onLocationChangedListener; 245 | if (mLocationClient == null) { 246 | try { 247 | mLocationClient = new AMapLocationClient(context); 248 | AMapLocationClientOption locationOption = new AMapLocationClientOption(); 249 | mLocationClient.setLocationListener(this); 250 | //设置为高精度定位模式 251 | locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); 252 | //设置定位参数 253 | mLocationClient.setLocationOption(locationOption); 254 | mLocationClient.startLocation(); 255 | } catch (Exception e) { 256 | e.printStackTrace(); 257 | } 258 | } 259 | } 260 | 261 | @Override 262 | public void deactivate() { 263 | mListener = null; 264 | if (mLocationClient != null) { 265 | mLocationClient.stopLocation(); 266 | mLocationClient.onDestroy(); 267 | } 268 | mLocationClient = null; 269 | } 270 | 271 | private final StringBuilder builder = new StringBuilder(); 272 | 273 | @Override 274 | public void onPoiSearched(PoiResult result, int code) { 275 | 276 | builder.delete(0, builder.length()); 277 | // 拼接json(避免引用gson之类的库,小插件不必要。。。) 278 | builder.append("["); 279 | 280 | if (code == AMapException.CODE_AMAP_SUCCESS) { 281 | // 搜索poi的结果 282 | if (result != null && result.getQuery() != null) { 283 | // 是否是同一条 284 | if (result.getQuery().equals(query)) { 285 | final List list = result.getPois(); 286 | 287 | for (int i = 0; i < list.size(); i++) { 288 | PoiItem item = list.get(i); 289 | builder.append("{"); 290 | builder.append("\"cityCode\": \"");builder.append(item.getCityCode());builder.append("\","); 291 | builder.append("\"cityName\": \"");builder.append(item.getCityName());builder.append("\","); 292 | builder.append("\"provinceName\": \"");builder.append(item.getProvinceName());builder.append("\","); 293 | builder.append("\"title\": \"");builder.append(item.getTitle());builder.append("\","); 294 | builder.append("\"adName\": \"");builder.append(item.getAdName());builder.append("\","); 295 | builder.append("\"provinceCode\": \"");builder.append(item.getProvinceCode());builder.append("\","); 296 | builder.append("\"latitude\": \"");builder.append(item.getLatLonPoint().getLatitude());builder.append("\","); 297 | builder.append("\"longitude\": \"");builder.append(item.getLatLonPoint().getLongitude());builder.append("\""); 298 | builder.append("},"); 299 | if (i == list.size() - 1) { 300 | builder.deleteCharAt(builder.length() - 1); 301 | } 302 | } 303 | 304 | if (list.size() > 0) { 305 | aMap.moveCamera(CameraUpdateFactory.zoomTo(16)); 306 | move(list.get(0).getLatLonPoint().getLatitude(), list.get(0).getLatLonPoint().getLongitude()); 307 | } 308 | } 309 | } 310 | } 311 | builder.append("]"); 312 | postMessageRunnable = new Runnable() { 313 | @Override 314 | public void run() { 315 | Map map = new HashMap<>(2); 316 | map.put("poiSearchResult", builder.toString()); 317 | methodChannel.invokeMethod("poiSearchResult", map); 318 | } 319 | }; 320 | if (platformThreadHandler.getLooper() == Looper.myLooper()) { 321 | postMessageRunnable.run(); 322 | } else { 323 | platformThreadHandler.post(postMessageRunnable); 324 | } 325 | } 326 | 327 | @Override 328 | public void onPoiItemSearched(PoiItem poiItem, int i) { 329 | 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /android/src/main/java/com/weilu/flutter/flutter_2d_amap/Flutter2dAmapPlugin.java: -------------------------------------------------------------------------------- 1 | package com.weilu.flutter.flutter_2d_amap; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.amap.api.location.AMapLocationClient; 6 | import com.amap.api.services.core.ServiceSettings; 7 | 8 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 9 | import io.flutter.embedding.engine.plugins.activity.ActivityAware; 10 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; 11 | import io.flutter.plugin.common.BinaryMessenger; 12 | import io.flutter.plugin.common.MethodCall; 13 | import io.flutter.plugin.common.MethodChannel; 14 | 15 | /** 16 | * Flutter2dAmapPlugin 17 | * @author weilu 18 | * */ 19 | public class Flutter2dAmapPlugin implements FlutterPlugin, ActivityAware{ 20 | 21 | private AMap2DDelegate delegate; 22 | private FlutterPluginBinding pluginBinding; 23 | private ActivityPluginBinding activityBinding; 24 | private MethodChannel methodChannel; 25 | 26 | public Flutter2dAmapPlugin() {} 27 | 28 | // /** Plugin registration. */ 29 | // public static void registerWith(Registrar registrar) { 30 | // if (registrar.activity() == null) { 31 | // return; 32 | // } 33 | // // 添加权限回调监听 34 | // final AMap2DDelegate delegate = new AMap2DDelegate(registrar.activity()); 35 | // registrar.addRequestPermissionsResultListener(delegate); 36 | // registrar.platformViewRegistry().registerViewFactory("plugins.weilu/flutter_2d_amap", new AMap2DFactory(registrar.messenger(), delegate)); 37 | // } 38 | 39 | @Override 40 | public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { 41 | pluginBinding = binding; 42 | } 43 | 44 | @Override 45 | public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { 46 | pluginBinding = null; 47 | } 48 | 49 | @Override 50 | public void onAttachedToActivity(@NonNull final ActivityPluginBinding binding) { 51 | activityBinding = binding; 52 | 53 | BinaryMessenger messenger = pluginBinding.getBinaryMessenger(); 54 | AMap2DFactory mFactory = new AMap2DFactory(messenger, null); 55 | pluginBinding.getPlatformViewRegistry().registerViewFactory("plugins.weilu/flutter_2d_amap", mFactory); 56 | 57 | delegate = new AMap2DDelegate(binding.getActivity()); 58 | binding.addRequestPermissionsResultListener(delegate); 59 | mFactory.setDelegate(delegate); 60 | 61 | methodChannel = new MethodChannel(messenger, "plugins.weilu/flutter_2d_amap_"); 62 | methodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() { 63 | @Override 64 | public void onMethodCall(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) { 65 | String method = methodCall.method; 66 | switch(method) { 67 | case "updatePrivacy": 68 | boolean isAgree = "true".equals(methodCall.arguments); 69 | ServiceSettings.updatePrivacyShow(binding.getActivity(), isAgree, isAgree); 70 | ServiceSettings.updatePrivacyAgree(binding.getActivity(), isAgree); 71 | AMapLocationClient.updatePrivacyShow(binding.getActivity(), isAgree, isAgree); 72 | AMapLocationClient.updatePrivacyAgree(binding.getActivity(), isAgree); 73 | break; 74 | default: 75 | break; 76 | } 77 | } 78 | }); 79 | 80 | } 81 | 82 | @Override 83 | public void onDetachedFromActivity() { 84 | tearDown(); 85 | } 86 | 87 | @Override 88 | public void onDetachedFromActivityForConfigChanges() { 89 | onDetachedFromActivity(); 90 | } 91 | 92 | @Override 93 | public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { 94 | onAttachedToActivity(binding); 95 | } 96 | 97 | private void tearDown() { 98 | activityBinding.removeRequestPermissionsResultListener(delegate); 99 | activityBinding = null; 100 | delegate = null; 101 | methodChannel.setMethodCallHandler(null); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxxhdpi/yd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/android/src/main/res/drawable-xxxhdpi/yd.png -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .flutter-plugins-dependencies 26 | .packages 27 | .pub-cache/ 28 | .pub/ 29 | /build/ 30 | 31 | # Android related 32 | **/android/**/gradle-wrapper.jar 33 | **/android/.gradle 34 | **/android/captures/ 35 | **/android/gradlew 36 | **/android/gradlew.bat 37 | **/android/local.properties 38 | **/android/**/GeneratedPluginRegistrant.java 39 | 40 | # iOS/XCode related 41 | **/ios/**/*.mode1v3 42 | **/ios/**/*.mode2v3 43 | **/ios/**/*.moved-aside 44 | **/ios/**/*.pbxuser 45 | **/ios/**/*.perspectivev3 46 | **/ios/**/*sync/ 47 | **/ios/**/.sconsign.dblite 48 | **/ios/**/.tags* 49 | **/ios/**/.vagrant/ 50 | **/ios/**/DerivedData/ 51 | **/ios/**/Icon? 52 | **/ios/**/Pods/ 53 | **/ios/**/.symlinks/ 54 | **/ios/**/profile 55 | **/ios/**/xcuserdata 56 | **/ios/.generated/ 57 | **/ios/Flutter/App.framework 58 | **/ios/Flutter/Flutter.framework 59 | **/ios/Flutter/Generated.xcconfig 60 | **/ios/Flutter/app.flx 61 | **/ios/Flutter/app.zip 62 | **/ios/Flutter/flutter_assets/ 63 | **/ios/ServiceDefinitions.json 64 | **/ios/Runner/GeneratedPluginRegistrant.* 65 | **/ios/Flutter/flutter_export_environment.sh 66 | **/ios/Flutter/.last_build_id 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 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_2d_amap_example 2 | 3 | Demonstrates how to use the flutter_2d_amap plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | def keystorePropertiesFile = rootProject.file("app/key.properties") 28 | def keystoreProperties = new Properties() 29 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 30 | 31 | android { 32 | compileSdkVersion 33 33 | 34 | lintOptions { 35 | disable 'InvalidPackage' 36 | } 37 | 38 | defaultConfig { 39 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 40 | applicationId "com.weilu.flutter.flutter_2d_amap_example" 41 | minSdkVersion flutter.minSdkVersion 42 | targetSdkVersion 33 43 | versionCode flutterVersionCode.toInteger() 44 | versionName flutterVersionName 45 | } 46 | 47 | signingConfigs { 48 | release { 49 | keyAlias keystoreProperties['keyAlias'] 50 | keyPassword keystoreProperties['keyPassword'] 51 | storeFile file(keystoreProperties['storeFile']) 52 | storePassword keystoreProperties['storePassword'] 53 | } 54 | } 55 | 56 | buildTypes { 57 | debug { 58 | signingConfig signingConfigs.release 59 | } 60 | release { 61 | // flutter build apk 62 | signingConfig signingConfigs.release 63 | } 64 | } 65 | } 66 | 67 | flutter { 68 | source '../..' 69 | } 70 | 71 | dependencies { 72 | testImplementation 'junit:junit:4.12' 73 | } 74 | -------------------------------------------------------------------------------- /example/android/app/key.properties: -------------------------------------------------------------------------------- 1 | storePassword=111111 2 | keyPassword=111111 3 | keyAlias=key0 4 | storeFile=../app/test.jks -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 14 | 17 | 18 | 26 | 27 | 28 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/weilu/flutter/flutter_2d_amap_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.weilu.flutter.flutter_2d_amap_example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/test.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/android/app/test.jks -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:4.2.2' 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 | tasks.register("clean", Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # This podspec is NOT to be published. It is only used as a local source! 3 | # This is a generated file; do not edit or check into version control. 4 | # 5 | 6 | Pod::Spec.new do |s| 7 | s.name = 'Flutter' 8 | s.version = '1.0.0' 9 | s.summary = 'A UI toolkit for beautiful and fast apps.' 10 | s.homepage = 'https://flutter.dev' 11 | s.license = { :type => 'BSD' } 12 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } 13 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } 14 | s.ios.deployment_target = '11.0' 15 | # Framework linking is handled by Flutter tooling, not CocoaPods. 16 | # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs. 17 | s.vendored_frameworks = 'path/to/nothing' 18 | end 19 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '11.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 flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 32 | end 33 | 34 | post_install do |installer| 35 | installer.pods_project.targets.each do |target| 36 | flutter_additional_ios_build_settings(target) 37 | target.build_configurations.each do |config| 38 | config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386' 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AMap2DMap (5.6.1): 3 | - AMapFoundation (~> 1.4) 4 | - AMapFoundation (1.6.9) 5 | - AMapLocation (2.8.0): 6 | - AMapFoundation (~> 1.6.9) 7 | - AMapSearch (8.1.0): 8 | - AMapFoundation (~> 1.6.9) 9 | - Flutter (1.0.0) 10 | - flutter_2d_amap (0.0.1): 11 | - AMap2DMap 12 | - AMapLocation (~> 2.8.0) 13 | - AMapSearch (~> 8.1.0) 14 | - Flutter 15 | 16 | DEPENDENCIES: 17 | - Flutter (from `Flutter`) 18 | - flutter_2d_amap (from `.symlinks/plugins/flutter_2d_amap/ios`) 19 | 20 | SPEC REPOS: 21 | trunk: 22 | - AMap2DMap 23 | - AMapFoundation 24 | - AMapLocation 25 | - AMapSearch 26 | 27 | EXTERNAL SOURCES: 28 | Flutter: 29 | :path: Flutter 30 | flutter_2d_amap: 31 | :path: ".symlinks/plugins/flutter_2d_amap/ios" 32 | 33 | SPEC CHECKSUMS: 34 | AMap2DMap: cac76bc057de18a1641f34df6b50bf5bc6b23571 35 | AMapFoundation: 8d8ecbb0b2e9ce5487995360d26c885d94642bfd 36 | AMapLocation: 5ef44a1117be7dc541cb7a7d43d03c5ee91e4387 37 | AMapSearch: 5c1cc07429f04b9cc76438fcb2411c66fdbbb178 38 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 39 | flutter_2d_amap: d116fde15b095d09399c5f754f52015c829fa718 40 | 41 | PODFILE CHECKSUM: 5f03b1eaae5eca60e9a57a199f5f74fa6f5f3c21 42 | 43 | COCOAPODS: 1.11.2 44 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 2A73E53E41C1DBD9A339B687 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9EB8F5E1F75AA0CBA690815 /* libPods-Runner.a */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 14 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 35 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 36 | 34A532F1DB51356CD0DDA32E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 37 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 38 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 39 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 40 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 41 | 86648C3FFDD3D46E7F6C36B9 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 44 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 47 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 49 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | A9EB8F5E1F75AA0CBA690815 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | DDD0FC0482E1ECD3349F4A25 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 2A73E53E41C1DBD9A339B687 /* libPods-Runner.a in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 4AC02B5EC08A589A9251CA09 /* Pods */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | DDD0FC0482E1ECD3349F4A25 /* Pods-Runner.debug.xcconfig */, 70 | 34A532F1DB51356CD0DDA32E /* Pods-Runner.release.xcconfig */, 71 | 86648C3FFDD3D46E7F6C36B9 /* Pods-Runner.profile.xcconfig */, 72 | ); 73 | name = Pods; 74 | sourceTree = ""; 75 | }; 76 | 70BF5918F5500467D30AB35D /* Frameworks */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | A9EB8F5E1F75AA0CBA690815 /* libPods-Runner.a */, 80 | ); 81 | name = Frameworks; 82 | sourceTree = ""; 83 | }; 84 | 9740EEB11CF90186004384FC /* Flutter */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 88 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 89 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 90 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 91 | ); 92 | name = Flutter; 93 | sourceTree = ""; 94 | }; 95 | 97C146E51CF9000F007C117D = { 96 | isa = PBXGroup; 97 | children = ( 98 | 9740EEB11CF90186004384FC /* Flutter */, 99 | 97C146F01CF9000F007C117D /* Runner */, 100 | 97C146EF1CF9000F007C117D /* Products */, 101 | 4AC02B5EC08A589A9251CA09 /* Pods */, 102 | 70BF5918F5500467D30AB35D /* Frameworks */, 103 | ); 104 | sourceTree = ""; 105 | }; 106 | 97C146EF1CF9000F007C117D /* Products */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 97C146EE1CF9000F007C117D /* Runner.app */, 110 | ); 111 | name = Products; 112 | sourceTree = ""; 113 | }; 114 | 97C146F01CF9000F007C117D /* Runner */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 118 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 119 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 120 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 121 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 122 | 97C147021CF9000F007C117D /* Info.plist */, 123 | 97C146F11CF9000F007C117D /* Supporting Files */, 124 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 125 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 126 | ); 127 | path = Runner; 128 | sourceTree = ""; 129 | }; 130 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 97C146F21CF9000F007C117D /* main.m */, 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | /* End PBXGroup section */ 139 | 140 | /* Begin PBXNativeTarget section */ 141 | 97C146ED1CF9000F007C117D /* Runner */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 144 | buildPhases = ( 145 | 8A2E2C58E4AB0D59B80B3D60 /* [CP] Check Pods Manifest.lock */, 146 | 9740EEB61CF901F6004384FC /* Run Script */, 147 | 97C146EA1CF9000F007C117D /* Sources */, 148 | 97C146EB1CF9000F007C117D /* Frameworks */, 149 | 97C146EC1CF9000F007C117D /* Resources */, 150 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 151 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 152 | 4F1E4DAFD65D4C996E3F8DAB /* [CP] Copy Pods Resources */, 153 | ); 154 | buildRules = ( 155 | ); 156 | dependencies = ( 157 | ); 158 | name = Runner; 159 | productName = Runner; 160 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 161 | productType = "com.apple.product-type.application"; 162 | }; 163 | /* End PBXNativeTarget section */ 164 | 165 | /* Begin PBXProject section */ 166 | 97C146E61CF9000F007C117D /* Project object */ = { 167 | isa = PBXProject; 168 | attributes = { 169 | LastUpgradeCheck = 1300; 170 | ORGANIZATIONNAME = "The Chromium Authors"; 171 | TargetAttributes = { 172 | 97C146ED1CF9000F007C117D = { 173 | CreatedOnToolsVersion = 7.3.1; 174 | }; 175 | }; 176 | }; 177 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 178 | compatibilityVersion = "Xcode 3.2"; 179 | developmentRegion = en; 180 | hasScannedForEncodings = 0; 181 | knownRegions = ( 182 | en, 183 | Base, 184 | ); 185 | mainGroup = 97C146E51CF9000F007C117D; 186 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 187 | projectDirPath = ""; 188 | projectRoot = ""; 189 | targets = ( 190 | 97C146ED1CF9000F007C117D /* Runner */, 191 | ); 192 | }; 193 | /* End PBXProject section */ 194 | 195 | /* Begin PBXResourcesBuildPhase section */ 196 | 97C146EC1CF9000F007C117D /* Resources */ = { 197 | isa = PBXResourcesBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 201 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 202 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 203 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXShellScriptBuildPhase section */ 210 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 211 | isa = PBXShellScriptBuildPhase; 212 | alwaysOutOfDate = 1; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | ); 216 | inputPaths = ( 217 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 218 | ); 219 | name = "Thin Binary"; 220 | outputPaths = ( 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | shellPath = /bin/sh; 224 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 225 | }; 226 | 4F1E4DAFD65D4C996E3F8DAB /* [CP] Copy Pods Resources */ = { 227 | isa = PBXShellScriptBuildPhase; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | ); 231 | inputPaths = ( 232 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", 233 | "${PODS_ROOT}/AMap2DMap/MAMapKit.framework/AMap.bundle", 234 | ); 235 | name = "[CP] Copy Pods Resources"; 236 | outputPaths = ( 237 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AMap.bundle", 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | shellPath = /bin/sh; 241 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; 242 | showEnvVarsInLog = 0; 243 | }; 244 | 8A2E2C58E4AB0D59B80B3D60 /* [CP] Check Pods Manifest.lock */ = { 245 | isa = PBXShellScriptBuildPhase; 246 | buildActionMask = 2147483647; 247 | files = ( 248 | ); 249 | inputPaths = ( 250 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 251 | "${PODS_ROOT}/Manifest.lock", 252 | ); 253 | name = "[CP] Check Pods Manifest.lock"; 254 | outputPaths = ( 255 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | shellPath = /bin/sh; 259 | 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"; 260 | showEnvVarsInLog = 0; 261 | }; 262 | 9740EEB61CF901F6004384FC /* Run Script */ = { 263 | isa = PBXShellScriptBuildPhase; 264 | alwaysOutOfDate = 1; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | ); 268 | inputPaths = ( 269 | ); 270 | name = "Run Script"; 271 | outputPaths = ( 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | shellPath = /bin/sh; 275 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 276 | }; 277 | /* End PBXShellScriptBuildPhase section */ 278 | 279 | /* Begin PBXSourcesBuildPhase section */ 280 | 97C146EA1CF9000F007C117D /* Sources */ = { 281 | isa = PBXSourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 285 | 97C146F31CF9000F007C117D /* main.m in Sources */, 286 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | /* End PBXSourcesBuildPhase section */ 291 | 292 | /* Begin PBXVariantGroup section */ 293 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 294 | isa = PBXVariantGroup; 295 | children = ( 296 | 97C146FB1CF9000F007C117D /* Base */, 297 | ); 298 | name = Main.storyboard; 299 | sourceTree = ""; 300 | }; 301 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 302 | isa = PBXVariantGroup; 303 | children = ( 304 | 97C147001CF9000F007C117D /* Base */, 305 | ); 306 | name = LaunchScreen.storyboard; 307 | sourceTree = ""; 308 | }; 309 | /* End PBXVariantGroup section */ 310 | 311 | /* Begin XCBuildConfiguration section */ 312 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 313 | isa = XCBuildConfiguration; 314 | buildSettings = { 315 | ALWAYS_SEARCH_USER_PATHS = NO; 316 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 317 | CLANG_ANALYZER_NONNULL = YES; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 323 | CLANG_WARN_BOOL_CONVERSION = YES; 324 | CLANG_WARN_COMMA = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 328 | CLANG_WARN_EMPTY_BODY = YES; 329 | CLANG_WARN_ENUM_CONVERSION = YES; 330 | CLANG_WARN_INFINITE_RECURSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 333 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 337 | CLANG_WARN_STRICT_PROTOTYPES = YES; 338 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 342 | COPY_PHASE_STRIP = NO; 343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 344 | ENABLE_NS_ASSERTIONS = NO; 345 | ENABLE_STRICT_OBJC_MSGSEND = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu99; 347 | GCC_NO_COMMON_BLOCKS = YES; 348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 350 | GCC_WARN_UNDECLARED_SELECTOR = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 355 | MTL_ENABLE_DEBUG_INFO = NO; 356 | SDKROOT = iphoneos; 357 | TARGETED_DEVICE_FAMILY = "1,2"; 358 | VALIDATE_PRODUCT = YES; 359 | }; 360 | name = Profile; 361 | }; 362 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 363 | isa = XCBuildConfiguration; 364 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 365 | buildSettings = { 366 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 367 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 368 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64"; 369 | DEVELOPMENT_TEAM = S8QB4VV633; 370 | ENABLE_BITCODE = NO; 371 | FRAMEWORK_SEARCH_PATHS = ( 372 | "$(inherited)", 373 | "$(PROJECT_DIR)/Flutter", 374 | ); 375 | INFOPLIST_FILE = Runner/Info.plist; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 377 | LIBRARY_SEARCH_PATHS = ( 378 | "$(inherited)", 379 | "$(PROJECT_DIR)/Flutter", 380 | ); 381 | PRODUCT_BUNDLE_IDENTIFIER = com.weilu.flutter.flutter2dAmapExample; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | VERSIONING_SYSTEM = "apple-generic"; 384 | }; 385 | name = Profile; 386 | }; 387 | 97C147031CF9000F007C117D /* Debug */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 392 | CLANG_ANALYZER_NONNULL = YES; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 398 | CLANG_WARN_BOOL_CONVERSION = YES; 399 | CLANG_WARN_COMMA = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 402 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 403 | CLANG_WARN_EMPTY_BODY = YES; 404 | CLANG_WARN_ENUM_CONVERSION = YES; 405 | CLANG_WARN_INFINITE_RECURSION = YES; 406 | CLANG_WARN_INT_CONVERSION = YES; 407 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 409 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 412 | CLANG_WARN_STRICT_PROTOTYPES = YES; 413 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 414 | CLANG_WARN_UNREACHABLE_CODE = YES; 415 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 416 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 417 | COPY_PHASE_STRIP = NO; 418 | DEBUG_INFORMATION_FORMAT = dwarf; 419 | ENABLE_STRICT_OBJC_MSGSEND = YES; 420 | ENABLE_TESTABILITY = YES; 421 | GCC_C_LANGUAGE_STANDARD = gnu99; 422 | GCC_DYNAMIC_NO_PIC = NO; 423 | GCC_NO_COMMON_BLOCKS = YES; 424 | GCC_OPTIMIZATION_LEVEL = 0; 425 | GCC_PREPROCESSOR_DEFINITIONS = ( 426 | "DEBUG=1", 427 | "$(inherited)", 428 | ); 429 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 430 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 431 | GCC_WARN_UNDECLARED_SELECTOR = YES; 432 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 433 | GCC_WARN_UNUSED_FUNCTION = YES; 434 | GCC_WARN_UNUSED_VARIABLE = YES; 435 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 436 | MTL_ENABLE_DEBUG_INFO = YES; 437 | ONLY_ACTIVE_ARCH = YES; 438 | SDKROOT = iphoneos; 439 | TARGETED_DEVICE_FAMILY = "1,2"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147041CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ALWAYS_SEARCH_USER_PATHS = NO; 447 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 448 | CLANG_ANALYZER_NONNULL = YES; 449 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 450 | CLANG_CXX_LIBRARY = "libc++"; 451 | CLANG_ENABLE_MODULES = YES; 452 | CLANG_ENABLE_OBJC_ARC = YES; 453 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 454 | CLANG_WARN_BOOL_CONVERSION = YES; 455 | CLANG_WARN_COMMA = YES; 456 | CLANG_WARN_CONSTANT_CONVERSION = YES; 457 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 458 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 459 | CLANG_WARN_EMPTY_BODY = YES; 460 | CLANG_WARN_ENUM_CONVERSION = YES; 461 | CLANG_WARN_INFINITE_RECURSION = YES; 462 | CLANG_WARN_INT_CONVERSION = YES; 463 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 464 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 465 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 466 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 467 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 468 | CLANG_WARN_STRICT_PROTOTYPES = YES; 469 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 470 | CLANG_WARN_UNREACHABLE_CODE = YES; 471 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 472 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 473 | COPY_PHASE_STRIP = NO; 474 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 475 | ENABLE_NS_ASSERTIONS = NO; 476 | ENABLE_STRICT_OBJC_MSGSEND = YES; 477 | GCC_C_LANGUAGE_STANDARD = gnu99; 478 | GCC_NO_COMMON_BLOCKS = YES; 479 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 480 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 481 | GCC_WARN_UNDECLARED_SELECTOR = YES; 482 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 483 | GCC_WARN_UNUSED_FUNCTION = YES; 484 | GCC_WARN_UNUSED_VARIABLE = YES; 485 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 486 | MTL_ENABLE_DEBUG_INFO = NO; 487 | SDKROOT = iphoneos; 488 | TARGETED_DEVICE_FAMILY = "1,2"; 489 | VALIDATE_PRODUCT = YES; 490 | }; 491 | name = Release; 492 | }; 493 | 97C147061CF9000F007C117D /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 496 | buildSettings = { 497 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 498 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 499 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64"; 500 | ENABLE_BITCODE = NO; 501 | FRAMEWORK_SEARCH_PATHS = ( 502 | "$(inherited)", 503 | "$(PROJECT_DIR)/Flutter", 504 | ); 505 | INFOPLIST_FILE = Runner/Info.plist; 506 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 507 | LIBRARY_SEARCH_PATHS = ( 508 | "$(inherited)", 509 | "$(PROJECT_DIR)/Flutter", 510 | ); 511 | PRODUCT_BUNDLE_IDENTIFIER = com.weilu.flutter.flutter2dAmapExample; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | VERSIONING_SYSTEM = "apple-generic"; 514 | }; 515 | name = Debug; 516 | }; 517 | 97C147071CF9000F007C117D /* Release */ = { 518 | isa = XCBuildConfiguration; 519 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 520 | buildSettings = { 521 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 522 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 523 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64"; 524 | ENABLE_BITCODE = NO; 525 | FRAMEWORK_SEARCH_PATHS = ( 526 | "$(inherited)", 527 | "$(PROJECT_DIR)/Flutter", 528 | ); 529 | INFOPLIST_FILE = Runner/Info.plist; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | LIBRARY_SEARCH_PATHS = ( 532 | "$(inherited)", 533 | "$(PROJECT_DIR)/Flutter", 534 | ); 535 | PRODUCT_BUNDLE_IDENTIFIER = com.weilu.flutter.flutter2dAmapExample; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | VERSIONING_SYSTEM = "apple-generic"; 538 | }; 539 | name = Release; 540 | }; 541 | /* End XCBuildConfiguration section */ 542 | 543 | /* Begin XCConfigurationList section */ 544 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 545 | isa = XCConfigurationList; 546 | buildConfigurations = ( 547 | 97C147031CF9000F007C117D /* Debug */, 548 | 97C147041CF9000F007C117D /* Release */, 549 | 249021D3217E4FDB00AE95B9 /* Profile */, 550 | ); 551 | defaultConfigurationIsVisible = 0; 552 | defaultConfigurationName = Release; 553 | }; 554 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 555 | isa = XCConfigurationList; 556 | buildConfigurations = ( 557 | 97C147061CF9000F007C117D /* Debug */, 558 | 97C147071CF9000F007C117D /* Release */, 559 | 249021D4217E4FDB00AE95B9 /* Profile */, 560 | ); 561 | defaultConfigurationIsVisible = 0; 562 | defaultConfigurationName = Release; 563 | }; 564 | /* End XCConfigurationList section */ 565 | }; 566 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 567 | } 568 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSAppTransportSecurity 6 | 7 | NSAllowsArbitraryLoads 8 | 9 | 10 | NSLocationAlwaysAndWhenInUseUsageDescription 11 | 地图功能需要您的定位服务,否则无法使用,如果您需要使用后台定位功能请选择“始终允许”。 12 | NSLocationAlwaysUsageDescription 13 | 地图功能需要您的定位服务,否则无法使用。 14 | NSLocationWhenInUseUsageDescription 15 | 地图功能需要您的定位服务,否则无法使用。 16 | io.flutter.embedded_views_preview 17 | 18 | CFBundleDevelopmentRegion 19 | en 20 | CFBundleExecutable 21 | $(EXECUTABLE_NAME) 22 | CFBundleIdentifier 23 | $(PRODUCT_BUNDLE_IDENTIFIER) 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | flutter_2d_amap_example 28 | CFBundlePackageType 29 | APPL 30 | CFBundleShortVersionString 31 | $(FLUTTER_BUILD_NAME) 32 | CFBundleSignature 33 | ???? 34 | CFBundleVersion 35 | $(FLUTTER_BUILD_NUMBER) 36 | LSRequiresIPhoneOS 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIMainStoryboardFile 41 | Main 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | UISupportedInterfaceOrientations~ipad 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationPortraitUpsideDown 52 | UIInterfaceOrientationLandscapeLeft 53 | UIInterfaceOrientationLandscapeRight 54 | 55 | UIViewControllerBasedStatusBarAppearance 56 | 57 | CADisableMinimumFrameDurationOnPhone 58 | 59 | UIApplicationSupportsIndirectInputEvents 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: depend_on_referenced_packages 2 | 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_2d_amap/flutter_2d_amap.dart'; 6 | 7 | void main() { 8 | WidgetsFlutterBinding.ensureInitialized(); 9 | Flutter2dAMap.updatePrivacy(true); 10 | Flutter2dAMap.setApiKey( 11 | iOSKey: '1a8f6a489483534a9f2ca96e4eeeb9b3', 12 | webKey: '4e479545913a3a180b3cffc267dad646', 13 | ).then((value) => runApp(const MyApp())); 14 | } 15 | 16 | class MyApp extends StatefulWidget { 17 | 18 | const MyApp({super.key}); 19 | 20 | @override 21 | _MyAppState createState() => _MyAppState(); 22 | } 23 | 24 | class _MyAppState extends State { 25 | 26 | List _list = []; 27 | int _index = 0; 28 | final ScrollController _controller = ScrollController(); 29 | late AMap2DController? _aMap2DController; 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | return MaterialApp( 34 | home: Scaffold( 35 | appBar: AppBar( 36 | title: const Text('flutter_2d_amap'), 37 | ), 38 | body: SafeArea( 39 | child: Column( 40 | children: [ 41 | Expanded( 42 | flex: 9, 43 | child: AMap2DView( 44 | onPoiSearched: (result) { 45 | if (result.isEmpty) { 46 | if (kDebugMode) { 47 | print('无搜索结果返回'); 48 | } 49 | return; 50 | } 51 | _controller.animateTo(0.0, duration: const Duration(milliseconds: 10), curve: Curves.ease); 52 | setState(() { 53 | _index = 0; 54 | _list = result; 55 | }); 56 | }, 57 | onAMap2DViewCreated: (controller) { 58 | _aMap2DController = controller; 59 | }, 60 | ), 61 | ), 62 | Expanded( 63 | flex: 11, 64 | child: ListView.separated( 65 | controller: _controller, 66 | shrinkWrap: true, 67 | itemCount: _list.length, 68 | separatorBuilder: (_, index) { 69 | return const Divider(height: 0.6); 70 | }, 71 | itemBuilder: (_, index) { 72 | return InkWell( 73 | onTap: () { 74 | setState(() { 75 | _index = index; 76 | if (_aMap2DController != null) { 77 | _aMap2DController?.move(_list[index].latitude ?? '', _list[index].longitude ?? ''); 78 | } 79 | }); 80 | }, 81 | child: Container( 82 | alignment: Alignment.centerLeft, 83 | padding: const EdgeInsets.symmetric(horizontal: 16.0), 84 | height: 50.0, 85 | child: Row( 86 | children: [ 87 | Expanded( 88 | child: Text( 89 | '${_list[index].provinceName!} ${_list[index].cityName!} ${_list[index].adName!} ${_list[index].title!}', 90 | ), 91 | ), 92 | Opacity( 93 | opacity: _index == index ? 1 : 0, 94 | child: const Icon(Icons.done, color: Colors.blue) 95 | ) 96 | ], 97 | ), 98 | ), 99 | ); 100 | } 101 | ), 102 | ) 103 | ], 104 | ), 105 | ), 106 | ), 107 | ); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.18.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_2d_amap: 58 | dependency: "direct dev" 59 | description: 60 | path: ".." 61 | relative: true 62 | source: path 63 | version: "0.3.0+3" 64 | flutter_test: 65 | dependency: "direct dev" 66 | description: flutter 67 | source: sdk 68 | version: "0.0.0" 69 | js: 70 | dependency: transitive 71 | description: 72 | name: js 73 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 74 | url: "https://pub.flutter-io.cn" 75 | source: hosted 76 | version: "0.6.7" 77 | leak_tracker: 78 | dependency: transitive 79 | description: 80 | name: leak_tracker 81 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 82 | url: "https://pub.flutter-io.cn" 83 | source: hosted 84 | version: "10.0.5" 85 | leak_tracker_flutter_testing: 86 | dependency: transitive 87 | description: 88 | name: leak_tracker_flutter_testing 89 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 90 | url: "https://pub.flutter-io.cn" 91 | source: hosted 92 | version: "3.0.5" 93 | leak_tracker_testing: 94 | dependency: transitive 95 | description: 96 | name: leak_tracker_testing 97 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 98 | url: "https://pub.flutter-io.cn" 99 | source: hosted 100 | version: "3.0.1" 101 | matcher: 102 | dependency: transitive 103 | description: 104 | name: matcher 105 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 106 | url: "https://pub.flutter-io.cn" 107 | source: hosted 108 | version: "0.12.16+1" 109 | material_color_utilities: 110 | dependency: transitive 111 | description: 112 | name: material_color_utilities 113 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 114 | url: "https://pub.flutter-io.cn" 115 | source: hosted 116 | version: "0.11.1" 117 | meta: 118 | dependency: transitive 119 | description: 120 | name: meta 121 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 122 | url: "https://pub.flutter-io.cn" 123 | source: hosted 124 | version: "1.15.0" 125 | path: 126 | dependency: transitive 127 | description: 128 | name: path 129 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 130 | url: "https://pub.flutter-io.cn" 131 | source: hosted 132 | version: "1.9.0" 133 | sky_engine: 134 | dependency: transitive 135 | description: flutter 136 | source: sdk 137 | version: "0.0.99" 138 | source_span: 139 | dependency: transitive 140 | description: 141 | name: source_span 142 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 143 | url: "https://pub.flutter-io.cn" 144 | source: hosted 145 | version: "1.10.0" 146 | stack_trace: 147 | dependency: transitive 148 | description: 149 | name: stack_trace 150 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 151 | url: "https://pub.flutter-io.cn" 152 | source: hosted 153 | version: "1.11.1" 154 | stream_channel: 155 | dependency: transitive 156 | description: 157 | name: stream_channel 158 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 159 | url: "https://pub.flutter-io.cn" 160 | source: hosted 161 | version: "2.1.2" 162 | string_scanner: 163 | dependency: transitive 164 | description: 165 | name: string_scanner 166 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 167 | url: "https://pub.flutter-io.cn" 168 | source: hosted 169 | version: "1.2.0" 170 | term_glyph: 171 | dependency: transitive 172 | description: 173 | name: term_glyph 174 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 175 | url: "https://pub.flutter-io.cn" 176 | source: hosted 177 | version: "1.2.1" 178 | test_api: 179 | dependency: transitive 180 | description: 181 | name: test_api 182 | sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" 183 | url: "https://pub.flutter-io.cn" 184 | source: hosted 185 | version: "0.7.2" 186 | vector_math: 187 | dependency: transitive 188 | description: 189 | name: vector_math 190 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 191 | url: "https://pub.flutter-io.cn" 192 | source: hosted 193 | version: "2.1.4" 194 | vm_service: 195 | dependency: transitive 196 | description: 197 | name: vm_service 198 | sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc 199 | url: "https://pub.flutter-io.cn" 200 | source: hosted 201 | version: "14.2.4" 202 | sdks: 203 | dart: ">=3.3.0 <4.0.0" 204 | flutter: ">=3.18.0-18.0.pre.54" 205 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_2d_amap_example 2 | description: Demonstrates how to use the flutter_2d_amap plugin. 3 | publish_to: 'flutter_2d_amap' 4 | 5 | environment: 6 | sdk: ">=3.0.0-0 <4.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | 12 | dev_dependencies: 13 | flutter_test: 14 | sdk: flutter 15 | 16 | flutter_2d_amap: 17 | path: ../ 18 | 19 | # For information on the generic Dart part of this file, see the 20 | # following page: https://www.dartlang.org/tools/pub/pubspec 21 | 22 | # The following section is specific to Flutter. 23 | flutter: 24 | 25 | # The following line ensures that the Material Icons font is 26 | # included with your application, so that you can use the icons in 27 | # the material Icons class. 28 | uses-material-design: true 29 | 30 | # To add assets to your application, add an assets section, like this: 31 | # assets: 32 | # - images/a_dot_burr.jpeg 33 | # - images/a_dot_ham.jpeg 34 | 35 | # An image asset can refer to one or more resolution-specific "variants", see 36 | # https://flutter.dev/assets-and-images/#resolution-aware. 37 | 38 | # For details regarding adding assets from package dependencies, see 39 | # https://flutter.dev/assets-and-images/#from-packages 40 | 41 | # To add custom fonts to your application, add a fonts section here, 42 | # in this "flutter" section. Each entry in this list should have a 43 | # "family" key with the font family name, and a "fonts" key with a 44 | # list giving the asset and other descriptors for the font. For 45 | # example: 46 | # fonts: 47 | # - family: Schyler 48 | # fonts: 49 | # - asset: fonts/Schyler-Regular.ttf 50 | # - asset: fonts/Schyler-Italic.ttf 51 | # style: italic 52 | # - family: Trajan Pro 53 | # fonts: 54 | # - asset: fonts/TrajanPro.ttf 55 | # - asset: fonts/TrajanPro_Bold.ttf 56 | # weight: 700 57 | # 58 | # For details regarding fonts from package dependencies, 59 | # see https://flutter.dev/custom-fonts/#from-packages 60 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter_2d_amap_example/main.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | void main() { 12 | testWidgets('Verify Platform version', (WidgetTester tester) async { 13 | // Build our app and trigger a frame. 14 | await tester.pumpWidget(const MyApp()); 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | flutter_2d_amap_example 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_2d_amap_example", 3 | "short_name": "flutter_2d_amap_example", 4 | "start_url": ".", 5 | "display": "minimal-ui", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "Demonstrates how to use the flutter_2d_amap plugin.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /flutter_2d_amap.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/Flutter2dAmapPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface Flutter2dAmapPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/Flutter2dAmapPlugin.m: -------------------------------------------------------------------------------- 1 | #import "Flutter2dAmapPlugin.h" 2 | #import "AMapFoundationKit/AMapFoundationKit.h" 3 | #import "FlutterAMap2D.h" 4 | #import "AMapSearchAPI.h" 5 | #import "AMapLocationManager.h" 6 | 7 | @implementation Flutter2dAmapPlugin 8 | + (void)registerWithRegistrar:(NSObject*)registrar { 9 | FlutterMethodChannel* channel = [FlutterMethodChannel 10 | methodChannelWithName:@"plugins.weilu/flutter_2d_amap_" 11 | binaryMessenger:[registrar messenger]]; 12 | Flutter2dAmapPlugin* instance = [[Flutter2dAmapPlugin alloc] init]; 13 | [registrar addMethodCallDelegate:instance channel:channel]; 14 | 15 | FlutterAMap2DFactory* aMap2DFactory = 16 | [[FlutterAMap2DFactory alloc] initWithMessenger:registrar.messenger]; 17 | [registrar registerViewFactory:aMap2DFactory withId:@"plugins.weilu/flutter_2d_amap"]; 18 | } 19 | 20 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 21 | if ([@"setKey" isEqualToString:call.method]) { 22 | NSString *key = call.arguments; 23 | [AMapServices sharedServices].enableHTTPS = YES; 24 | // 配置高德地图的key 25 | [AMapServices sharedServices].apiKey = key; 26 | result(@YES); 27 | } else if ([@"updatePrivacy" isEqualToString:call.method]) { 28 | if ([@"true" isEqualToString:call.arguments]) { 29 | [AMapSearchAPI updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain]; 30 | [AMapSearchAPI updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree]; 31 | [AMapLocationManager updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain]; 32 | [AMapLocationManager updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree]; 33 | } else { 34 | [AMapSearchAPI updatePrivacyShow:AMapPrivacyShowStatusNotShow privacyInfo:AMapPrivacyInfoStatusNotContain]; 35 | [AMapSearchAPI updatePrivacyAgree:AMapPrivacyAgreeStatusNotAgree]; 36 | [AMapLocationManager updatePrivacyShow:AMapPrivacyShowStatusNotShow privacyInfo:AMapPrivacyInfoStatusNotContain]; 37 | [AMapLocationManager updatePrivacyAgree:AMapPrivacyAgreeStatusNotAgree]; 38 | } 39 | result(@YES); 40 | } else { 41 | result(FlutterMethodNotImplemented); 42 | } 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /ios/Classes/FlutterAMap2D.h: -------------------------------------------------------------------------------- 1 | // 2 | // FlutterAMap2D.h 3 | // flutter_2d_amap 4 | // 5 | // Created by weilu on 2019/7/1. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FlutterAMap2DController : NSObject 14 | 15 | - (instancetype)initWithFrame:(CGRect)frame 16 | viewIdentifier:(int64_t)viewId 17 | arguments:(id _Nullable)args 18 | binaryMessenger:(NSObject*)messenger; 19 | 20 | - (UIView*)view; 21 | 22 | - (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode; 23 | 24 | @end 25 | 26 | @interface FlutterAMap2DFactory : NSObject 27 | - (instancetype)initWithMessenger:(NSObject*)messenger; 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /ios/Classes/FlutterAMap2D.m: -------------------------------------------------------------------------------- 1 | // 2 | // FlutterAMap2D.m 3 | // flutter_2d_amap 4 | // 5 | // Created by weilu on 2019/7/1. 6 | // 7 | 8 | #import "FlutterAMap2D.h" 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | 16 | @implementation FlutterAMap2DFactory { 17 | NSObject* _messenger; 18 | } 19 | 20 | - (instancetype)initWithMessenger:(NSObject*)messenger { 21 | self = [super init]; 22 | if (self) { 23 | _messenger = messenger; 24 | } 25 | return self; 26 | } 27 | 28 | - (NSObject*)createArgsCodec { 29 | return [FlutterStandardMessageCodec sharedInstance]; 30 | } 31 | 32 | - (NSObject*)createWithFrame:(CGRect)frame 33 | viewIdentifier:(int64_t)viewId 34 | arguments:(id _Nullable)args { 35 | FlutterAMap2DController* aMap2DController = [[FlutterAMap2DController alloc] initWithFrame:frame 36 | viewIdentifier:viewId 37 | arguments:args 38 | binaryMessenger:_messenger]; 39 | return aMap2DController; 40 | } 41 | 42 | @end 43 | 44 | 45 | @interface FlutterAMap2DController() 46 | 47 | @property (strong, nonatomic) CLLocationManager *mannger; 48 | @property (strong, nonatomic) AMapLocationManager *locationManager; 49 | @property (strong, nonatomic) AMapSearchAPI *search; 50 | @end 51 | 52 | @implementation FlutterAMap2DController { 53 | MAMapView* _mapView; 54 | int64_t _viewId; 55 | FlutterMethodChannel* _channel; 56 | 57 | MAPointAnnotation* _pointAnnotation; 58 | bool _isPoiSearch; 59 | } 60 | 61 | NSString* _types = @"010000|010100|020000|030000|040000|050000|050100|060000|060100|060200|060300|060400|070000|080000|080100|080300|080500|080600|090000|090100|090200|090300|100000|100100|110000|110100|120000|120200|120300|130000|140000|141200|150000|150100|150200|160000|160100|170000|170100|170200|180000|190000|200000"; 62 | 63 | - (instancetype)initWithFrame:(CGRect)frame 64 | viewIdentifier:(int64_t)viewId 65 | arguments:(id _Nullable)args 66 | binaryMessenger:(NSObject*)messenger { 67 | if ([super init]) { 68 | 69 | _viewId = viewId; 70 | NSString* channelName = [NSString stringWithFormat:@"plugins.weilu/flutter_2d_amap_%lld", viewId]; 71 | _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; 72 | __weak __typeof__(self) weakSelf = self; 73 | [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { 74 | [weakSelf onMethodCall:call result:result]; 75 | }]; 76 | _isPoiSearch = [args[@"isPoiSearch"] boolValue] == YES; 77 | /// 初始化地图 78 | _mapView = [[MAMapView alloc] initWithFrame:frame]; 79 | _mapView.delegate = self; 80 | // 请求定位权限 81 | self.mannger = [[CLLocationManager alloc] init]; 82 | self.mannger.delegate = self; 83 | [self.mannger requestWhenInUseAuthorization]; 84 | } 85 | return self; 86 | } 87 | 88 | -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { 89 | switch (status) { 90 | case kCLAuthorizationStatusAuthorizedAlways: 91 | case kCLAuthorizationStatusAuthorizedWhenInUse:{ 92 | _mapView.showsUserLocation = YES; 93 | _mapView.userTrackingMode = MAUserTrackingModeFollow; 94 | 95 | /// 初始化定位 96 | self.locationManager = [[AMapLocationManager alloc] init]; 97 | self.locationManager.delegate = self; 98 | /// 开始定位 99 | [self.locationManager startUpdatingLocation]; 100 | /// 初始化搜索 101 | self.search = [[AMapSearchAPI alloc] init]; 102 | self.search.delegate = self; 103 | break; 104 | } 105 | default: 106 | NSLog(@"授权失败"); 107 | break; 108 | } 109 | } 110 | 111 | #pragma mark 点击地图方法 112 | - (void)mapView:(MAMapView *)mapView didSingleTappedAtCoordinate:(CLLocationCoordinate2D)coordinate { 113 | [self->_mapView setCenterCoordinate:coordinate animated:YES]; 114 | [self drawMarkers:coordinate.latitude lon:coordinate.longitude]; 115 | [self searchPOI:coordinate.latitude lon:coordinate.longitude]; 116 | } 117 | 118 | //接收位置更新,实现AMapLocationManagerDelegate代理的amapLocationManager:didUpdateLocation方法,处理位置更新 119 | - (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ 120 | CLLocationCoordinate2D center; 121 | center.latitude = location.coordinate.latitude; 122 | center.longitude = location.coordinate.longitude; 123 | [_mapView setZoomLevel:17 animated: YES]; 124 | [_mapView setCenterCoordinate:center animated:YES]; 125 | [self.locationManager stopUpdatingLocation]; 126 | [self searchPOI:location.coordinate.latitude lon:location.coordinate.longitude]; 127 | } 128 | 129 | /* POI 搜索回调. */ 130 | - (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response{ 131 | if (response.pois.count == 0) { 132 | NSDictionary* arguments = @{@"poiSearchResult" : @"[]"}; 133 | [_channel invokeMethod:@"poiSearchResult" arguments:arguments]; 134 | return; 135 | } 136 | 137 | //1. 初始化可变字符串,存放最终生成json字串 138 | NSMutableString *jsonString = [[NSMutableString alloc] initWithString:@"["]; 139 | 140 | [response.pois enumerateObjectsUsingBlock:^(AMapPOI *obj, NSUInteger idx, BOOL *stop) { 141 | 142 | if (idx == 0) { 143 | CLLocationCoordinate2D center; 144 | center.latitude = obj.location.latitude; 145 | center.longitude = obj.location.longitude; 146 | [self->_mapView setZoomLevel:17 animated: YES]; 147 | [self->_mapView setCenterCoordinate:center animated:YES]; 148 | [self drawMarkers:obj.location.latitude lon:obj.location.longitude]; 149 | } 150 | //2. 遍历数组,取出键值对并按json格式存放 151 | NSString *string = [NSString stringWithFormat:@"{\"cityCode\":\"%@\",\"cityName\":\"%@\",\"provinceName\":\"%@\",\"title\":\"%@\",\"adName\":\"%@\",\"provinceCode\":\"%@\",\"latitude\":\"%f\",\"longitude\":\"%f\"},", obj.citycode, obj.city, obj.province, obj.name, obj.district, obj.pcode, obj.location.latitude, obj.location.longitude]; 152 | [jsonString appendString:string]; 153 | 154 | }]; 155 | 156 | // 3. 获取末尾逗号所在位置 157 | NSUInteger location = [jsonString length] - 1; 158 | 159 | NSRange range = NSMakeRange(location, 1); 160 | 161 | // 4. 将末尾逗号换成结束的] 162 | [jsonString replaceCharactersInRange:range withString:@"]"]; 163 | 164 | NSDictionary* arguments = @{ 165 | @"poiSearchResult" : jsonString 166 | }; 167 | [_channel invokeMethod:@"poiSearchResult" arguments:arguments]; 168 | 169 | } 170 | 171 | //字典转Json 172 | - (NSString*)dictionaryToJson:(NSDictionary *)dic { 173 | NSError *parseError = nil; 174 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError]; 175 | return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 176 | } 177 | 178 | - (UIView*)view { 179 | return _mapView; 180 | } 181 | 182 | //检查是否授予定位权限 183 | - (bool)hasPermission{ 184 | CLAuthorizationStatus locationStatus = [CLLocationManager authorizationStatus]; 185 | return (bool)(locationStatus == kCLAuthorizationStatusAuthorizedWhenInUse || locationStatus == kCLAuthorizationStatusAuthorizedAlways); 186 | } 187 | 188 | - (void)drawMarkers:(CGFloat)lat lon:(CGFloat)lon { 189 | if (self->_pointAnnotation == NULL) { 190 | self->_pointAnnotation = [[MAPointAnnotation alloc] init]; 191 | self->_pointAnnotation.coordinate = CLLocationCoordinate2DMake(lat, lon); 192 | [self->_mapView addAnnotation:self->_pointAnnotation]; 193 | } else { 194 | self->_pointAnnotation.coordinate = CLLocationCoordinate2DMake(lat, lon); 195 | } 196 | } 197 | 198 | - (void)searchPOI:(CGFloat)lat lon:(CGFloat)lon{ 199 | 200 | if (_isPoiSearch) { 201 | AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init]; 202 | request.types = _types; 203 | request.requireExtension = YES; 204 | request.offset = 50; 205 | request.location = [AMapGeoPoint locationWithLatitude:lat longitude:lon]; 206 | [self.search AMapPOIAroundSearch:request]; 207 | } 208 | } 209 | 210 | - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 211 | if ([[call method] isEqualToString:@"search"]) { 212 | if (_isPoiSearch) { 213 | AMapPOIKeywordsSearchRequest *request = [[AMapPOIKeywordsSearchRequest alloc] init]; 214 | request.types = _types; 215 | request.requireExtension = YES; 216 | request.offset = 50; 217 | request.keywords = [call arguments][@"keyWord"]; 218 | request.city = [call arguments][@"city"]; 219 | [self.search AMapPOIKeywordsSearch:request]; 220 | } 221 | } else if ([[call method] isEqualToString:@"move"]) { 222 | NSString* lat = [call arguments][@"lat"]; 223 | NSString* lon = [call arguments][@"lon"]; 224 | CLLocationCoordinate2D center; 225 | center.latitude = [lat doubleValue]; 226 | center.longitude = [lon doubleValue]; 227 | [self->_mapView setCenterCoordinate:center animated:YES]; 228 | [self drawMarkers:[lat doubleValue] lon:[lon doubleValue]]; 229 | } else if ([[call method] isEqualToString:@"location"]) { 230 | [self.locationManager startUpdatingLocation]; 231 | } 232 | } 233 | @end 234 | -------------------------------------------------------------------------------- /ios/flutter_2d_amap.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'flutter_2d_amap' 6 | s.version = '0.0.1' 7 | s.summary = 'A new Flutter plugin.' 8 | s.description = <<-DESC 9 | A new Flutter plugin. 10 | DESC 11 | s.homepage = 'https://github.com/simplezhli' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'weilu' => 'a05111993@163.com' } 14 | s.source = { :path => '.' } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | s.dependency 'AMap2DMap' 19 | s.dependency 'AMapSearch', "~> 8.1.0" 20 | s.dependency 'AMapLocation', "~> 2.8.0" 21 | s.static_framework = true 22 | s.ios.deployment_target = '9.0' 23 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } 24 | end 25 | 26 | -------------------------------------------------------------------------------- /lib/flutter_2d_amap.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | 4 | import 'package:flutter/foundation.dart'; 5 | import 'package:flutter/services.dart'; 6 | 7 | export 'src/amap_2d_view.dart'; 8 | export 'src/interface/amap_2d_controller.dart'; 9 | export 'src/poi_search_model.dart'; 10 | 11 | class Flutter2dAMap { 12 | static const MethodChannel _channel = MethodChannel('plugins.weilu/flutter_2d_amap_'); 13 | 14 | static String _webKey = ''; 15 | static String get webKey => _webKey; 16 | 17 | static Future setApiKey({String iOSKey = '', String webKey = ''}) async { 18 | if (kIsWeb) { 19 | _webKey = webKey; 20 | } else { 21 | if (Platform.isIOS) { 22 | return _channel.invokeMethod('setKey', iOSKey); 23 | } 24 | } 25 | return Future.value(true); 26 | } 27 | 28 | /// 更新同意隐私状态,需要在初始化地图之前完成 29 | static Future updatePrivacy(bool isAgree) async { 30 | if (kIsWeb) { 31 | 32 | } else { 33 | if (Platform.isIOS || Platform.isAndroid) { 34 | await _channel.invokeMethod('updatePrivacy', isAgree.toString()); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/src/amap_2d_view.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_2d_amap/src/interface/amap_2d_controller.dart'; 4 | 5 | import 'amap_2d_view_state.dart' 6 | if (dart.library.html) 'web/amap_2d_view_state.dart' 7 | if (dart.library.io) 'mobile/amap_2d_view_state.dart'; 8 | 9 | import 'poi_search_model.dart'; 10 | 11 | 12 | typedef AMap2DViewCreatedCallback = void Function(AMap2DController controller); 13 | 14 | class AMap2DView extends StatefulWidget { 15 | 16 | const AMap2DView({ 17 | super.key, 18 | this.isPoiSearch = true, 19 | this.onPoiSearched, 20 | this.onAMap2DViewCreated, 21 | }); 22 | 23 | final bool isPoiSearch; 24 | final AMap2DViewCreatedCallback? onAMap2DViewCreated; 25 | final Function(List)? onPoiSearched; 26 | 27 | @override 28 | AMap2DViewState createState() => AMap2DViewState(); 29 | } 30 | -------------------------------------------------------------------------------- /lib/src/amap_2d_view_state.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | import 'package:flutter_2d_amap/flutter_2d_amap.dart'; 5 | 6 | class AMap2DViewState extends State { 7 | @override 8 | Widget build(BuildContext context) { 9 | return Text('$defaultTargetPlatform is not yet supported by the flutter_2d_amap plugin'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/src/interface/amap_2d_controller.dart: -------------------------------------------------------------------------------- 1 | 2 | abstract class AMap2DController { 3 | 4 | /// city:cityName(中文或中文全拼)、cityCode均可 5 | Future search(String keyWord, {String city = ''}); 6 | 7 | Future move(String lat, String lon); 8 | 9 | Future location(); 10 | } 11 | -------------------------------------------------------------------------------- /lib/src/mobile/amap_2d_controller.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'dart:convert'; 3 | 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_2d_amap/flutter_2d_amap.dart'; 6 | 7 | class AMap2DMobileController extends AMap2DController { 8 | AMap2DMobileController( 9 | int id, 10 | this._widget, 11 | ) : _channel = MethodChannel('plugins.weilu/flutter_2d_amap_$id') { 12 | _channel.setMethodCallHandler(_handleMethod); 13 | } 14 | final MethodChannel _channel; 15 | 16 | final AMap2DView _widget; 17 | 18 | Future _handleMethod(MethodCall call) async { 19 | final String method = call.method; 20 | switch(method) { 21 | case 'poiSearchResult': 22 | { 23 | if (_widget.onPoiSearched != null) { 24 | final Map args = call.arguments as Map; 25 | final List list = []; 26 | for (final value in json.decode(args['poiSearchResult'] as String) as List) { 27 | list.add(PoiSearch.fromJsonMap(value as Map)); 28 | } 29 | _widget.onPoiSearched!(list); 30 | } 31 | return Future.value(''); 32 | } 33 | } 34 | return Future.value(''); 35 | } 36 | 37 | /// city:cityName(中文或中文全拼)、cityCode均可 38 | @override 39 | Future search(String keyWord, {String city = ''}) async { 40 | return _channel.invokeMethod('search', { 41 | 'keyWord': keyWord, 42 | 'city': city, 43 | }); 44 | } 45 | 46 | @override 47 | Future move(String lat, String lon) async { 48 | return _channel.invokeMethod('move', { 49 | 'lat': lat, 50 | 'lon': lon 51 | }); 52 | } 53 | 54 | @override 55 | Future location() async { 56 | return _channel.invokeMethod('location'); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/src/mobile/amap_2d_view_state.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | import 'dart:async'; 4 | 5 | import 'package:flutter/foundation.dart'; 6 | import 'package:flutter/services.dart'; 7 | import 'package:flutter/widgets.dart'; 8 | import 'package:flutter_2d_amap/flutter_2d_amap.dart'; 9 | import 'package:flutter_2d_amap/src/mobile/amap_2d_controller.dart'; 10 | 11 | 12 | class AMap2DViewState extends State { 13 | 14 | final Completer _controller = Completer(); 15 | 16 | void _onPlatformViewCreated(int id) { 17 | final AMap2DMobileController controller = AMap2DMobileController(id, widget); 18 | _controller.complete(controller); 19 | if (widget.onAMap2DViewCreated != null) { 20 | widget.onAMap2DViewCreated!(controller); 21 | } 22 | } 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | if (defaultTargetPlatform == TargetPlatform.android) { 27 | return AndroidView( 28 | viewType: 'plugins.weilu/flutter_2d_amap', 29 | onPlatformViewCreated: _onPlatformViewCreated, 30 | creationParams: _CreationParams.fromWidget(widget).toMap(), 31 | creationParamsCodec: const StandardMessageCodec(), 32 | ); 33 | } else if (defaultTargetPlatform == TargetPlatform.iOS) { 34 | return UiKitView( 35 | viewType: 'plugins.weilu/flutter_2d_amap', 36 | onPlatformViewCreated: _onPlatformViewCreated, 37 | creationParams: _CreationParams.fromWidget(widget).toMap(), 38 | creationParamsCodec: const StandardMessageCodec(), 39 | ); 40 | } 41 | return Text('$defaultTargetPlatform is not yet supported by the flutter_2d_amap plugin'); 42 | } 43 | } 44 | 45 | /// 需要更多的初始化配置,可以在此处添加 46 | class _CreationParams { 47 | _CreationParams({this.isPoiSearch = true}); 48 | 49 | static _CreationParams fromWidget(AMap2DView widget) { 50 | return _CreationParams( 51 | isPoiSearch: widget.isPoiSearch, 52 | ); 53 | } 54 | 55 | final bool isPoiSearch; 56 | 57 | Map toMap() { 58 | return { 59 | 'isPoiSearch': isPoiSearch, 60 | }; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/src/poi_search_model.dart: -------------------------------------------------------------------------------- 1 | 2 | class PoiSearch { 3 | 4 | PoiSearch({ 5 | this.cityCode, 6 | this.cityName, 7 | this.provinceName, 8 | this.title, 9 | this.adName, 10 | this.provinceCode, 11 | this.latitude, 12 | this.longitude, 13 | }); 14 | 15 | PoiSearch.fromJsonMap(Map map): 16 | cityCode = map['cityCode'] as String?, 17 | cityName = map['cityName'] as String?, 18 | provinceName = map['provinceName'] as String?, 19 | title = map['title'] as String?, 20 | adName = map['adName'] as String?, 21 | provinceCode = map['provinceCode'] as String?, 22 | latitude = map['latitude'] as String?, 23 | longitude = map['longitude'] as String?; 24 | 25 | String? cityCode; 26 | String? cityName; 27 | String? provinceName; 28 | String? title; 29 | String? adName; 30 | String? provinceCode; 31 | String? latitude; 32 | String? longitude; 33 | 34 | Map toJson() { 35 | final Map data = {}; 36 | data['cityCode'] = cityCode; 37 | data['cityName'] = cityName; 38 | data['provinceName'] = provinceName; 39 | data['title'] = title; 40 | data['adName'] = adName; 41 | data['provinceCode'] = provinceCode; 42 | data['latitude'] = latitude; 43 | data['longitude'] = longitude; 44 | return data; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/src/web/amap_2d_controller.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter_2d_amap/flutter_2d_amap.dart'; 4 | import 'package:flutter_2d_amap/src/web/amapjs.dart'; 5 | import 'package:js/js.dart'; 6 | 7 | class AMap2DWebController extends AMap2DController { 8 | 9 | AMap2DWebController(this._aMap, this._widget) { 10 | 11 | _placeSearchOptions = PlaceSearchOptions( 12 | extensions: 'all', 13 | type: _kType, 14 | pageIndex: 1, 15 | pageSize: 50, 16 | ); 17 | 18 | _aMap.on('click', allowInterop((event) { 19 | //_aMap.resize(); /// 2.0无法自适应容器大小,需手动调用触发计算。 20 | searchNearBy(LngLat(event.lnglat.getLng(), event.lnglat.getLat())); 21 | })); 22 | 23 | /// 定位插件初始化 24 | _geolocation = Geolocation(GeolocationOptions( 25 | timeout: 15000, 26 | buttonPosition: 'RT', 27 | buttonOffset: Pixel(10, 20), 28 | zoomToAccuracy: true, 29 | enableHighAccuracy: true, 30 | )); 31 | 32 | _aMap.addControl(_geolocation); 33 | location(); 34 | } 35 | 36 | final AMap2DView _widget; 37 | final AMap _aMap; 38 | late Geolocation _geolocation; 39 | MarkerOptions? _markerOptions; 40 | late PlaceSearchOptions _placeSearchOptions; 41 | static const String _kType = '010000|010100|020000|030000|040000|050000|050100|060000|060100|060200|060300|060400|070000|080000|080100|080300|080500|080600|090000|090100|090200|090300|100000|100100|110000|110100|120000|120200|120300|130000|140000|141200|150000|150100|150200|160000|160100|170000|170100|170200|180000|190000|200000'; 42 | 43 | /// city:cityName(中文或中文全拼)、cityCode均可 44 | @override 45 | Future search(String keyWord, {city = ''}) async { 46 | if (!_widget.isPoiSearch) { 47 | return; 48 | } 49 | final PlaceSearch placeSearch = PlaceSearch(_placeSearchOptions); 50 | placeSearch.setCity(city); 51 | placeSearch.search(keyWord, searchResult); 52 | return Future.value(); 53 | } 54 | 55 | @override 56 | Future move(String lat, String lon) async { 57 | final LngLat lngLat = LngLat(double.parse(lon), double.parse(lat)); 58 | _aMap.setCenter(lngLat); 59 | if (_markerOptions == null) { 60 | _markerOptions = MarkerOptions( 61 | position: lngLat, 62 | icon: AMapIcon(IconOptions( 63 | size: Size(26, 34), 64 | imageSize: Size(26, 34), 65 | image: 'https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png', 66 | )), 67 | offset: Pixel(-13, -34), 68 | anchor: 'bottom-center' 69 | ); 70 | 71 | } else { 72 | _markerOptions?.position = lngLat; 73 | } 74 | _aMap.clearMap(); 75 | _aMap.add(Marker(_markerOptions!)); 76 | return Future.value(); 77 | } 78 | 79 | @override 80 | Future location() async { 81 | _geolocation.getCurrentPosition(allowInterop((status, result) { 82 | if (status == 'complete') { 83 | _aMap.setZoom(17); 84 | _aMap.setCenter(result.position); 85 | searchNearBy(result.position); 86 | } else { 87 | /// 异常查询:https://lbs.amap.com/faq/js-api/map-js-api/position-related/43361 88 | /// Get geolocation time out:浏览器定位超时,包括原生的超时,可以适当增加超时属性的设定值以减少这一现象, 89 | /// 另外还有个别浏览器(如google Chrome浏览器等)本身的定位接口是黑洞,通过其请求定位完全没有回应,也会超时返回失败。 90 | if (kDebugMode) { 91 | print(result.message); 92 | } 93 | } 94 | })); 95 | return Future.value(); 96 | } 97 | 98 | /// 根据经纬度搜索 99 | void searchNearBy(LngLat lngLat) { 100 | if (!_widget.isPoiSearch) { 101 | return; 102 | } 103 | final PlaceSearch placeSearch = PlaceSearch(_placeSearchOptions); 104 | placeSearch.searchNearBy('', lngLat, 2000, searchResult); 105 | } 106 | 107 | Function(String status, SearchResult result) get searchResult => allowInterop((status, result) { 108 | final List list = []; 109 | if (status == 'complete') { 110 | result.poiList?.pois?.forEach((dynamic poi) { 111 | if (poi is Poi) { 112 | final PoiSearch poiSearch = PoiSearch( 113 | cityCode: poi.citycode, 114 | cityName: poi.cityname, 115 | provinceName: poi.pname, 116 | title: poi.name, 117 | adName: poi.adname, 118 | provinceCode: poi.pcode, 119 | latitude: poi.location.getLat().toString(), 120 | longitude: poi.location.getLng().toString(), 121 | ); 122 | list.add(poiSearch); 123 | } 124 | }); 125 | } else if (status == 'no_data'){ 126 | if (kDebugMode) { 127 | print('无返回结果'); 128 | } 129 | } else { 130 | if (kDebugMode) { 131 | print(result); 132 | } 133 | } 134 | /// 默认点移动到搜索结果的第一条 135 | if (list.isNotEmpty) { 136 | _aMap.setZoom(17); 137 | move(list[0].latitude!, list[0].longitude!); 138 | } 139 | 140 | if (_widget.onPoiSearched != null) { 141 | _widget.onPoiSearched!(list); 142 | } 143 | }); 144 | } 145 | -------------------------------------------------------------------------------- /lib/src/web/amap_2d_view_state.dart: -------------------------------------------------------------------------------- 1 | 2 | // ignore: avoid_web_libraries_in_flutter 3 | import 'dart:html'; 4 | import 'dart:js_util'; 5 | import 'dart:ui' as ui; 6 | 7 | import 'package:flutter/foundation.dart'; 8 | import 'package:flutter/scheduler.dart'; 9 | import 'package:flutter/widgets.dart'; 10 | import 'package:flutter_2d_amap/flutter_2d_amap.dart'; 11 | import 'package:flutter_2d_amap/src/web/amap_2d_controller.dart'; 12 | import 'package:flutter_2d_amap/src/web/amapjs.dart'; 13 | import 'package:flutter_2d_amap/src/web/loaderjs.dart'; 14 | 15 | class AMap2DViewState extends State { 16 | 17 | /// 加载的插件 18 | final List plugins = ['AMap.Geolocation', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.ToolBar']; 19 | 20 | late AMap _aMap; 21 | late String _divId; 22 | late DivElement _element; 23 | 24 | void _onPlatformViewCreated() { 25 | 26 | final Object promise = load(LoaderOptions( 27 | key: Flutter2dAMap.webKey, 28 | version: '1.4.15', // 2.0需要修改GeolocationOptions属性 29 | plugins: plugins, 30 | )) as Object; 31 | 32 | promiseToFuture(promise).then((dynamic value){ 33 | final MapOptions mapOptions = MapOptions( 34 | zoom: 11, 35 | resizeEnable: true, 36 | ); 37 | /// 无法使用id https://github.com/flutter/flutter/issues/40080 38 | _aMap = AMap(_element, mapOptions); 39 | /// 加载插件 40 | _aMap.plugin(plugins, allowInterop(() { 41 | _aMap.addControl(Scale()); 42 | _aMap.addControl(ToolBar()); 43 | 44 | final AMap2DWebController controller = AMap2DWebController(_aMap, widget); 45 | if (widget.onAMap2DViewCreated != null) { 46 | widget.onAMap2DViewCreated!(controller); 47 | } 48 | })); 49 | 50 | }, onError: (dynamic e) { 51 | if (kDebugMode) { 52 | print('初始化错误:$e'); 53 | } 54 | }); 55 | } 56 | 57 | @override 58 | void dispose() { 59 | _aMap.destroy(); 60 | super.dispose(); 61 | } 62 | 63 | @override 64 | void initState() { 65 | super.initState(); 66 | _divId = DateTime.now().toIso8601String(); 67 | /// 先创建div并注册 68 | // ignore: undefined_prefixed_name,avoid_dynamic_calls 69 | ui.platformViewRegistry.registerViewFactory(_divId, (int viewId) { 70 | _element = DivElement() 71 | ..style.width = '100%' 72 | ..style.height = '100%' 73 | ..style.margin = '0'; 74 | 75 | return _element; 76 | }); 77 | SchedulerBinding.instance.addPostFrameCallback((_) { 78 | /// 创建地图 79 | _onPlatformViewCreated(); 80 | }); 81 | } 82 | 83 | @override 84 | Widget build(BuildContext context) { 85 | return HtmlElementView( 86 | viewType: _divId, 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/src/web/amapjs.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: always_declare_return_types 2 | 3 | @JS('AMap') 4 | library amap; 5 | 6 | import 'package:js/js.dart'; 7 | 8 | /// 高德地图js,文档:https://lbs.amap.com/api/javascript-api/guide/abc/prepare 9 | @JS('Map') 10 | class AMap { 11 | external AMap(dynamic /*String|DivElement*/ div, MapOptions opts); 12 | /// 重新计算容器大小 13 | external resize(); 14 | /// 设置中心点 15 | external setCenter(LngLat center); 16 | /// 设置地图显示的缩放级别,参数 zoom 可设范围:[2, 20] 17 | external setZoom(num zoom); 18 | /// 添加覆盖物/图层。参数为单个覆盖物/图层,或覆盖物/图层的数组。 19 | external add(dynamic /*Array | Marker*/ features); 20 | /// 删除覆盖物/图层。参数为单个覆盖物/图层,或覆盖物/图层的数组。 21 | external remove(dynamic /*Array | Marker*/ features); 22 | /// 删除所有覆盖物 23 | external clearMap(); 24 | /// 加载插件 25 | external plugin(dynamic/*String|List*/ name, void Function() callback); 26 | /// 添加控件,参数可以是插件列表中的任何插件对象,如:ToolBar、OverView、Scale等 27 | external addControl(Control control); 28 | /// 销毁地图,并清空地图容器 29 | external destroy(); 30 | 31 | external on(String eventName, void Function(MapsEvent event) callback); 32 | } 33 | 34 | @JS() 35 | class Geolocation extends Control { 36 | external Geolocation(GeolocationOptions opts); 37 | external getCurrentPosition(Function(String status, GeolocationResult result) callback); 38 | } 39 | 40 | @JS() 41 | class PlaceSearch { 42 | external PlaceSearch(PlaceSearchOptions opts); 43 | external search(String keyword, Function(String status, SearchResult result) callback); 44 | /// 根据中心点经纬度、半径以及关键字进行周边查询 radius取值范围:0-50000 45 | external searchNearBy(String keyword, LngLat center, num radius, Function(String status, SearchResult result) callback); 46 | external setType(String type); 47 | external setPageIndex(int pageIndex); 48 | external setPageSize(int pageSize); 49 | external setCity(String city); 50 | } 51 | 52 | @JS() 53 | class LngLat { 54 | external LngLat(num lng, num lat); 55 | external num getLng(); 56 | external num getLat(); 57 | } 58 | 59 | @JS() 60 | class Pixel { 61 | external Pixel(num x, num y); 62 | } 63 | 64 | @JS() 65 | class Marker { 66 | external Marker(MarkerOptions opts); 67 | } 68 | 69 | @JS() 70 | class Control { 71 | external Control(); 72 | } 73 | 74 | @JS() 75 | class Scale extends Control { 76 | external Scale(); 77 | } 78 | 79 | @JS() 80 | class ToolBar extends Control { 81 | external ToolBar(); 82 | } 83 | 84 | @JS('Icon') 85 | class AMapIcon { 86 | external AMapIcon(IconOptions options); 87 | } 88 | 89 | @JS() 90 | class Size { 91 | external Size(num width, num height); 92 | } 93 | 94 | @JS() 95 | @anonymous 96 | class MapsEvent { 97 | external LngLat get lnglat; 98 | } 99 | 100 | @JS() 101 | @anonymous 102 | class MapOptions { 103 | 104 | external factory MapOptions({ 105 | /// 初始中心经纬度 106 | LngLat center, 107 | bool resizeEnable, 108 | /// 地图显示的缩放级别 109 | num zoom, 110 | /// 地图视图模式, 默认为‘2D’ 111 | String /*‘2D’|‘3D’*/ viewMode, 112 | }); 113 | 114 | external LngLat get center; 115 | external num get zoom; 116 | external String get viewMode; 117 | } 118 | 119 | @JS() 120 | @anonymous 121 | class MarkerOptions { 122 | 123 | external factory MarkerOptions({ 124 | /// 要显示该marker的地图对象 125 | AMap map, 126 | /// 点标记在地图上显示的位置 127 | LngLat position, 128 | AMapIcon icon, 129 | String title, 130 | Pixel offset, 131 | String anchor, 132 | }); 133 | 134 | external LngLat get position; 135 | external set position(LngLat v); 136 | } 137 | 138 | @JS() 139 | @anonymous 140 | class GeolocationOptions { 141 | external factory GeolocationOptions({ 142 | /// 是否使用高精度定位,默认:true 。2.0 默认为false 143 | bool enableHighAccuracy, 144 | /// 设置定位超时时间,默认:无穷大 145 | int timeout, 146 | /// 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)。 2.0为offset 147 | Pixel buttonOffset, 148 | /// 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false 149 | bool zoomToAccuracy, 150 | /// 定位按钮的排放位置, 'LT': 左上角, 'RT': 右上角, 'LB': 左下角, 'RB': 右下角。 2.0为position 151 | String /*‘LT’|‘RT’|‘LB’|‘RB’*/buttonPosition, 152 | }); 153 | } 154 | 155 | @JS() 156 | @anonymous 157 | class PlaceSearchOptions { 158 | external factory PlaceSearchOptions({ 159 | ///此项默认值:base,返回基本地址信息 160 | /// 取值:all,返回基本+详细信息 161 | String extensions, 162 | String type, 163 | int pageSize, 164 | int pageIndex, 165 | }); 166 | } 167 | 168 | @JS() 169 | @anonymous 170 | class IconOptions { 171 | external factory IconOptions({ 172 | Size size, 173 | String image, 174 | Size imageSize, 175 | }); 176 | } 177 | 178 | @JS() 179 | @anonymous 180 | class GeolocationResult { 181 | external LngLat get position; 182 | external String get message; 183 | } 184 | 185 | @JS() 186 | @anonymous 187 | class SearchResult { 188 | external PoiList? get poiList; 189 | /// 成功状态说明 190 | external String get info; 191 | } 192 | 193 | @JS() 194 | @anonymous 195 | class PoiList { 196 | external List? get pois; 197 | /// 查询结果总数 198 | external int get count; 199 | } 200 | 201 | @JS() 202 | @anonymous 203 | class Poi { 204 | external String get citycode; 205 | external String get cityname; 206 | external String get pname; 207 | external String get pcode; 208 | external LngLat get location; 209 | external String get adname; 210 | external String get name; 211 | } 212 | -------------------------------------------------------------------------------- /lib/src/web/html_element_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/gestures.dart'; 3 | import 'package:flutter/rendering.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter/widgets.dart'; 6 | 7 | // https://github.com/deakjahn/flutter_dropzone 8 | // https://github.com/flutter/flutter/issues/56181 9 | 10 | class HtmlElementViewEx extends HtmlElementView { 11 | 12 | const HtmlElementViewEx({super.key, required super.viewType, required this.onPlatformViewCreatedCallback, this.creationParams}); 13 | 14 | final PlatformViewCreatedCallback onPlatformViewCreatedCallback; //!!! 15 | final dynamic creationParams; 16 | 17 | @override 18 | Widget build(BuildContext context) => PlatformViewLink( 19 | viewType: viewType, 20 | onCreatePlatformView: _createHtmlElementView, 21 | surfaceFactory: (BuildContext context, PlatformViewController controller) => PlatformViewSurface( 22 | controller: controller, 23 | gestureRecognizers: const >{}, 24 | hitTestBehavior: PlatformViewHitTestBehavior.opaque, 25 | ), 26 | ); 27 | 28 | _HtmlElementViewControllerEx _createHtmlElementView(PlatformViewCreationParams params) { 29 | final _HtmlElementViewControllerEx controller = _HtmlElementViewControllerEx(params.id, viewType); 30 | controller._initialize().then((_) { 31 | params.onPlatformViewCreated(params.id); 32 | onPlatformViewCreatedCallback(params.id); //!!! 33 | }); 34 | return controller; 35 | } 36 | } 37 | 38 | class _HtmlElementViewControllerEx extends PlatformViewController { 39 | 40 | _HtmlElementViewControllerEx(this.viewId, this.viewType); 41 | 42 | @override 43 | final int viewId; 44 | final String viewType; 45 | bool _initialized = false; 46 | 47 | Future _initialize() async { 48 | await SystemChannels.platform_views.invokeMethod('create', {'id': viewId, 'viewType': viewType}); 49 | _initialized = true; 50 | } 51 | 52 | @override 53 | Future clearFocus() { 54 | return Future.value(); 55 | } 56 | 57 | @override 58 | Future dispatchPointerEvent(PointerEvent event) { 59 | return Future.value(); 60 | } 61 | 62 | @override 63 | Future dispose() { 64 | if (_initialized) { 65 | SystemChannels.platform_views.invokeMethod('dispose', viewId); 66 | } 67 | return Future.value(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/src/web/loaderjs.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: always_declare_return_types 2 | 3 | @JS('AMapLoader') 4 | library loader; 5 | 6 | import 'package:js/js.dart'; 7 | 8 | /// 高德地图 Loader js 9 | external load(LoaderOptions options); 10 | 11 | @JS() 12 | @anonymous 13 | class LoaderOptions { 14 | 15 | external factory LoaderOptions({ 16 | ///您申请的key值 17 | String? key, 18 | /// JSAPI 版本号 19 | String version, 20 | //同步加载的插件列表 (https://lbs.amap.com/api/jsapi-v2/guide/abc/plugins) 21 | List plugins, 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /preview/Screenshot_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simplezhli/flutter_2d_amap/0105ceae2e367d7411288245f927a6ffee6d61a9/preview/Screenshot_1.jpg -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.17.1" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_test: 58 | dependency: "direct dev" 59 | description: flutter 60 | source: sdk 61 | version: "0.0.0" 62 | js: 63 | dependency: "direct main" 64 | description: 65 | name: js 66 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 67 | url: "https://pub.flutter-io.cn" 68 | source: hosted 69 | version: "0.6.7" 70 | matcher: 71 | dependency: transitive 72 | description: 73 | name: matcher 74 | sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" 75 | url: "https://pub.flutter-io.cn" 76 | source: hosted 77 | version: "0.12.15" 78 | material_color_utilities: 79 | dependency: transitive 80 | description: 81 | name: material_color_utilities 82 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 83 | url: "https://pub.flutter-io.cn" 84 | source: hosted 85 | version: "0.2.0" 86 | meta: 87 | dependency: transitive 88 | description: 89 | name: meta 90 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" 91 | url: "https://pub.flutter-io.cn" 92 | source: hosted 93 | version: "1.9.1" 94 | path: 95 | dependency: transitive 96 | description: 97 | name: path 98 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "1.8.3" 102 | sky_engine: 103 | dependency: transitive 104 | description: flutter 105 | source: sdk 106 | version: "0.0.99" 107 | source_span: 108 | dependency: transitive 109 | description: 110 | name: source_span 111 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 112 | url: "https://pub.flutter-io.cn" 113 | source: hosted 114 | version: "1.9.1" 115 | stack_trace: 116 | dependency: transitive 117 | description: 118 | name: stack_trace 119 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 120 | url: "https://pub.flutter-io.cn" 121 | source: hosted 122 | version: "1.11.0" 123 | stream_channel: 124 | dependency: transitive 125 | description: 126 | name: stream_channel 127 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "2.1.1" 131 | string_scanner: 132 | dependency: transitive 133 | description: 134 | name: string_scanner 135 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 136 | url: "https://pub.flutter-io.cn" 137 | source: hosted 138 | version: "1.2.0" 139 | term_glyph: 140 | dependency: transitive 141 | description: 142 | name: term_glyph 143 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 144 | url: "https://pub.flutter-io.cn" 145 | source: hosted 146 | version: "1.2.1" 147 | test_api: 148 | dependency: transitive 149 | description: 150 | name: test_api 151 | sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb 152 | url: "https://pub.flutter-io.cn" 153 | source: hosted 154 | version: "0.5.1" 155 | vector_math: 156 | dependency: transitive 157 | description: 158 | name: vector_math 159 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 160 | url: "https://pub.flutter-io.cn" 161 | source: hosted 162 | version: "2.1.4" 163 | sdks: 164 | dart: ">=3.0.0-0 <4.0.0" 165 | flutter: ">=1.10.0" 166 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_2d_amap 2 | description: A flutter plugin for 2D amap. 3 | version: 0.3.0+3 4 | homepage: 'https://github.com/simplezhli/flutter_2d_amap' 5 | 6 | publish_to: 'none' 7 | 8 | environment: 9 | sdk: ">=3.0.0-0 <4.0.0" 10 | flutter: ">=1.10.0" 11 | 12 | dependencies: 13 | flutter: 14 | sdk: flutter 15 | # https://pub.flutter-io.cn/packages/js 16 | js: ^0.6.5 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | 22 | # For information on the generic Dart part of this file, see the 23 | # following page: https://www.dartlang.org/tools/pub/pubspec 24 | 25 | # The following section is specific to Flutter. 26 | flutter: 27 | # This section identifies this Flutter project as a plugin project. 28 | # The androidPackage and pluginClass identifiers should not ordinarily 29 | # be modified. They are used by the tooling to maintain consistency when 30 | # adding or updating assets for this project. 31 | plugin: 32 | platforms: 33 | android: 34 | package: com.weilu.flutter.flutter_2d_amap 35 | pluginClass: Flutter2dAmapPlugin 36 | ios: 37 | pluginClass: Flutter2dAmapPlugin 38 | -------------------------------------------------------------------------------- /test/flutter_2d_amap_test.dart: -------------------------------------------------------------------------------- 1 | 2 | void main() { 3 | } 4 | --------------------------------------------------------------------------------