Flutter高德地图搜索组件
2019-11-16 本文已影响0人
陌北v1
插件地址github:
https://github.com/fluttify-project/amap_search_fluttify
flutter pub:
https://pub.flutter-io.cn/packages/amap_search_fluttify
Flutter 签名方法(如果没有生成过签名文件,参考此文章)
https://www.jianshu.com/p/248eeb5d6535
Android Studio配置:
1.配置 android\app\src\main\AndroidManifest.xml文件
在AndroidManifest.xml的application
标签中配置Key(这一步不要搞错了。是application
标签中配置Key):
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="您的Key"/>
在AndroidManifest.xml中配置权限:
//地图包、搜索包需要的基础权限
<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序设置内置sd卡的写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序访问WiFi网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--允许程序访问CellID或WiFi热点来获取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
开始安装:
dependencies:
amap_search_fluttify: ^0.2.11+d2eb645
导入:
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
使用:
/// !注意: 只要是返回Future的方法, 一律使用`await`修饰, 确保当前方法执行完成后再执行下一行, 在不能使用`await`修饰的环境下, 在`then`方法中执行下一步.
/// 初始化 iOS在init方法中设置, android需要去AndroidManifest.xml里去设置, 详见https://lbs.amap.com/api/android-sdk/gettingstarted
await AmapCore.init('ios key');
/// !重要: 通过AmapSearchDisposeMixin释放native端的对象, 否则native端会内存泄漏!
class _KeywordPoiScreenState extends State<KeywordPoiScreen> with AmapSearchDisposeMixin {}
/// 搜索关键字poi
final poiList = await AmapSearch.searchKeyword(
_keywordController.text,
city: _cityController.text,
);
/// 搜索周边poi
final poiList = await AmapSearch.searchAround(
LatLng(
double.tryParse(_latController.text) ?? 29.08,
double.tryParse(_lngController.text) ?? 119.65,
),
keyword: _keywordController.text,
);
/// 输入提示
final inputTipList = await AmapSearch.fetchInputTips(
_keywordController.text,
city: _cityController.text,
);
/// 地理编码(地址转坐标)
final geocodeList = await AmapSearch.searchGeocode(
_keywordController.text,
city: _cityController.text,
);
/// 逆地理编码(坐标转地址)
final reGeocodeList = await AmapSearch.searchReGeocode(
LatLng(
double.parse(_latController.text),
double.parse(_lngController.text),
),
radius: 200.0,
);
/// 获取行政区划数据
final district = await AmapSearch.searchDistrict(_keywordController.text);
/// 获取天气数据
final district = await AmapSearch.searchDistrict(_keywordController.text);
/// 公交路径规划(未完成)
final routeResult = await AmapSearch.searchBusRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
city: '杭州',
);
/// 驾车路径规划
final routeResult = await AmapSearch.searchDriveRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
);
/// 骑行路径规划
final routeResult = await AmapSearch.searchRideRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
);
/// 步行路径规划
final routeResult = await AmapSearch.searchWalkRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
);
例子:
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:amap_search_fluttify_example/widgets/function_item.widget.dart';
import 'package:amap_search_fluttify_example/widgets/scrollable_text.widget.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
class GetPoiScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(title: Text('获取POI数据')),
body: ListView(
children: <Widget>[
FunctionItem(
label: '关键字检索POI',
sublabel: 'KeywordPoiScreen',
target: KeywordPoiScreen(),
),
FunctionItem(
label: '周边检索POI',
sublabel: 'AroundPoiScreen',
target: AroundPoiScreen(),
),
FunctionItem(
label: '输入提示',
sublabel: 'InputTipScreen',
target: InputTipScreen(),
),
],
),
);
}
}
/// 关键字检索POI
class KeywordPoiScreen extends StatefulWidget {
@override
_KeywordPoiScreenState createState() => _KeywordPoiScreenState();
}
class _KeywordPoiScreenState extends State<KeywordPoiScreen>
with AmapSearchDisposeMixin {
final _keywordController = TextEditingController(text: '肯德基');
final _cityController = TextEditingController(text: '杭州');
List<String> _poiTitleList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(title: Text('关键字检索POI')),
body: DecoratedColumn(
padding: EdgeInsets.all(kSpaceBig),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: InputDecoration(hintText: '输入关键字'),
),
TextFormField(
controller: _cityController,
decoration: InputDecoration(hintText: '输入城市'),
),
RaisedButton(
onPressed: () async {
final poiList = await AmapSearch.searchKeyword(
_keywordController.text,
city: _cityController.text,
);
Observable.fromIterable(poiList)
.asyncMap((it) async =>
'title: ' +
(await it.title) +
', address: ' +
(await it.address) +
', businessArea: ' +
(await it.businessArea) +
', ' +
(await it.latLng).toString())
.toList()
.then((it) => setState(() => _poiTitleList = it));
},
child: Text('搜索'),
),
Expanded(child: ScrollableText(_poiTitleList.join("\n"))),
],
),
);
}
}
/// 附近检索POI
class AroundPoiScreen extends StatefulWidget {
@override
_AroundPoiScreenState createState() => _AroundPoiScreenState();
}
class _AroundPoiScreenState extends State<AroundPoiScreen>
with AmapSearchDisposeMixin {
final _keywordController = TextEditingController();
final _typeController = TextEditingController();
final _latController = TextEditingController(text: '29.08');
final _lngController = TextEditingController(text: '119.65');
List<String> _poiTitleList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(title: Text('周边检索POI')),
body: DecoratedColumn(
padding: EdgeInsets.all(kSpaceBig),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: InputDecoration(hintText: '输入关键字'),
),
TextFormField(
controller: _typeController,
decoration: InputDecoration(hintText: '输入类别'),
),
DecoratedRow(
children: <Widget>[
Flexible(
child: TextField(
controller: _latController,
decoration: InputDecoration(hintText: '输入纬度'),
),
),
SPACE_SMALL_HORIZONTAL,
Flexible(
child: TextField(
controller: _lngController,
decoration: InputDecoration(hintText: '输入经度'),
),
),
],
),
RaisedButton(
onPressed: () async {
final poiList = await AmapSearch.searchAround(
LatLng(
double.tryParse(_latController.text) ?? 29.08,
double.tryParse(_lngController.text) ?? 119.65,
),
keyword: _keywordController.text,
type: _typeController.text,
);
Observable.fromIterable(poiList)
.asyncMap((it) async =>
'title: ' +
(await it.title) +
', address: ' +
(await it.address) +
', businessArea: ' +
(await it.businessArea) +
', ' +
(await it.latLng).toString())
.toList()
.then((it) => setState(() => _poiTitleList = it));
},
child: Text('搜索'),
),
Expanded(child: ScrollableText(_poiTitleList.join("\n"))),
],
),
);
}
}
/// 输入提示
class InputTipScreen extends StatefulWidget {
@override
_InputTipScreenState createState() => _InputTipScreenState();
}
class _InputTipScreenState extends State<InputTipScreen>
with AmapSearchDisposeMixin {
final _keywordController = TextEditingController(text: '肯德基');
final _cityController = TextEditingController(text: '杭州');
List<String> _inputTipList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(title: Text('输入内容自动提示')),
body: DecoratedColumn(
padding: EdgeInsets.all(kSpaceBig),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: InputDecoration(hintText: '输入关键字'),
),
TextFormField(
controller: _cityController,
decoration: InputDecoration(hintText: '输入所在城市'),
),
RaisedButton(
onPressed: () async {
final inputTipList = await AmapSearch.fetchInputTips(
_keywordController.text,
city: _cityController.text,
);
Observable.fromIterable(inputTipList)
.asyncMap((it) => it.toFutureString())
.toList()
.then((it) => setState(() => _inputTipList = it));
},
child: Text('搜索'),
),
Expanded(child: ScrollableText(_inputTipList.join("\n"))),
],
),
);
}
}