赞
踩
实现方式
第一步可以查看博客 这里就不讲了
博主使用的是高德官方提供的POI搜索接口(官网提供了大量的接口都可以使用 根据自己需要的可以去官网查看)https://developer.amap.com/api/webservice/guide/api/search
使用高德的接口的前提需要自己去 注册一个key
使用高德的搜索是申请Web服务API类型KEY 千万不要注册错了
注册好之后就是使用高德的接口查询数据
1.关键字搜索
接口地址:https://restapi.amap.com/v3/place/text
参数:key :你刚刚注册的web服务的key 必须传
keywords:查询关键字
city:查询城市
citylimit:仅返回指定城市数据(默认false) 可以改
offset:每页记录数据 强烈建议不超过25,若超过25可能造成访问报错
page:当前页数 最大翻页数100
更多参数可以查看查看文档
查看json可以直接复制下面的连接进去
https://restapi.amap.com/v3/place/text?key=fef4e35be05e2337119aeb3b4e57388d&keywords=%E6%B8%AF%E6%83%A0&city=%E6%83%A0%E5%B7%9E%E5%B8%82&offset=20&page=1&citylimit=true
2.根据经纬度获取附近信息
接口地址 : https://restapi.amap.com/v3/place/around
参数:key :你刚刚注册的web服务的key 必须传
keywords:查询关键字
city:查询城市
citylimit:仅返回指定城市数据(默认false) 可以改
offset:每页记录数据 强烈建议不超过25,若超过25可能造成访问报错
page:当前页数 最大翻页数100
location:中心点坐标(根据当前位置搜索附近的信息) 规则: 经度和纬度用","分割,经度在前,纬度在后,经纬度小数点后不得超过6位
更多参数可以查看查看文档
查看json可以直接复制下面的连接进去
https://restapi.amap.com/v3/place/around?key=fef4e35be05e2337119aeb3b4e57388d&keywords=&city=%E6%83%A0%E5%B7%9E%E5%B8%82&location=114.40497230523532,23.11071494684081&offset=20&page=1&citylimit=true
目前博主就使用了高德的搜索POI的这两个接口 有小伙伴需要使用其他的可以查看文档 都是一样的
使用的插件有 如果有报错 可能是使用的flutter版本不一样 博主的是flutter1.1.12.13
#状态管理 rxdart: ^0.21.0 random_string: ^1.1.0 modal_progress_hud: ^0.1.3 # 本地存储 shared_preferences: ^0.5.6+2 flutter_i18n: ^0.8.2 # 同步插件 synchronized: ^2.1.0+1 # 吐司插件 fluttertoast: ^3.1.0 #日期选择 flutter_cupertino_date_picker: ^1.0.7 date_format: ^1.0.6 #图片多选插件 multi_image_picker: ^4.5.9 #下拉菜单 dropdown_menu: ^1.1.1 #下拉菜单 gzx_dropdown_menu: ^1.0.3 #搜索 amap_search_fluttify: ^0.8.2+1 #权限 permission_handler: ^3.2.0 #定位 amap_location: ^0.2.0 provider: ^3.1.0 # 网络请求插件 dio: ^2.1.7 # 上拉下拉 flutter_easyrefresh: ^2.1.1 intl: ^0.16.0
另外代码贴上 复制到项目中可以直接使用
test.dart
import 'package:amap_location/amap_location.dart'; import 'package:amap_location/amap_location_option.dart'; import 'package:carbutlerflutter/http/http.dart'; import 'package:carbutlerflutter/model/peripheral_information_entity.dart'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:permission_handler/permission_handler.dart'; class TestWidget extends StatefulWidget { @override _TestWidgetState createState() => _TestWidgetState(); } class _TestWidgetState extends State<TestWidget> { @override void initState() { // TODO: implement initState super.initState(); init(); } init() async { /flutter定位 await AMapLocationClient.startup(new AMapLocationOption( desiredAccuracy: CLLocationAccuracy.kCLLocationAccuracyHundredMeters)); getLocation(); } AMapLocation currentAddressInfo = AMapLocation(); //当前位置的信息 TextEditingController searchController = TextEditingController(); //搜索关键字控制器 // List<model> modelList = []; int pageSize = 20; //一页大小 int pageIndex = 1; //当前页 int pages = 1; //总页数 List<PeripheralInformationPoi> pois; //返回页面显示的数据集合 String androidAMapKey = "fef4e35be05e2337119aeb3b4e57388d"; //安卓高德key 搜索POI需要 bool cityLimit = true; //仅返回指定城市数据 getLocation() async { // 申请权限 定位权限 Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler() .requestPermissions([PermissionGroup.location]); // 申请结果 PermissionStatus permission = await PermissionHandler() .checkPermissionStatus(PermissionGroup.location); print('PermissionStatus.granted${PermissionStatus.granted}'); if (permission == PermissionStatus.granted) { await AMapLocationClient.getLocation(true).then((_) { print('获取定位成功'); print('获取的latitude${_.latitude}'); print('获取的longitude${_.longitude}'); currentAddressInfo = _; //获取到当前定位的信息 aroundHttp(); Fluttertoast.showToast(msg: "定位成功"); }); } else { Fluttertoast.showToast(msg: "权限申请被拒绝"); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: Text('附近信息'), ), body:Container( child: Column( children: <Widget>[ //搜索框 Container( width: MediaQuery.of(context).size.width, height: 44, margin: EdgeInsets.symmetric( vertical: 12, ), padding: EdgeInsets.symmetric( horizontal:12, ), child: Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ //当前城市 InkWell( child: Container( padding: EdgeInsets.only(left: 10), margin: EdgeInsets.only(right: 5), child: Row( children: <Widget>[ Container( child: Text( '${currentAddressInfo.city ?? " "}', style: TextStyle(fontSize: 13), ), ), Icon( Icons.arrow_drop_down, color: Colors.grey[400], size: 20, ) ], ), ), onTap: () { //点击跳转到选择城市页面 }, ), //线 Container( width: 1, color: Colors.grey[400], margin: EdgeInsets.symmetric(vertical: 9), ), //输入框 Container( padding: EdgeInsets.only(left: 10), child: TextField( decoration: InputDecoration( hintText: "点击输入", hintStyle: TextStyle( fontSize: 14, color: Colors.grey[400], ), border: InputBorder.none, suffix: InkWell( child: Container( child: Image.asset( 'images/clear.png', width: 16, height: 16, fit: BoxFit.cover, ), ), onTap: () { searchController.text = ""; searchHttp(); }, ), ), controller: searchController, onSubmitted: (val) { //调用搜索接口 if (val == null || val == "" || val.length == 0) { return; } else { print('调用搜索接口'); searchHttp(); } }, onChanged: (val) { setState(() { }); }, style: TextStyle( fontSize: 14, color: Colors.grey[400], ), ), width: MediaQuery.of(context).size.width * 0.55, ), //搜索按钮 InkWell( child: Container( alignment: Alignment.centerRight, child: Center( child: Text( '搜索', style: TextStyle( fontSize: 14, color: Colors.white, ), ), ), width: MediaQuery.of(context).size.width * 0.17, decoration: BoxDecoration( color: Color(0xff2EA5F1), borderRadius: BorderRadius.circular(2)), ), onTap: () { //调用搜索接口 print('调用搜索接口'); searchHttp(); }, ), ], ), decoration: BoxDecoration( color: Color(0xffF0F0F0), borderRadius: BorderRadius.circular(4)), ), ), //数据列表 Expanded( child: Container( color: Colors.white, child: EasyRefresh( child: ListView( children: List.generate(pois.length, (index) { return InkWell( child: Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only( left: 12, bottom: 10, top: 10), margin: EdgeInsets.symmetric(vertical: 10), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ Image.asset( 'images/currentaddress.png', width: 12, height: 12, ), Container( width: 3, ), Expanded( child: Text( '${pois[index].name}', style: TextStyle( fontSize:13, color: Color(0xff333333)), softWrap: true, )), ], ), decoration: BoxDecoration( border: Border.all( color: Colors.grey[100], width: 1), ), ), onTap: () { //获取数据返回 }, ); }), ), //todo:刷新 onRefresh: () async { print('下拉刷新'); searchHttp(); }, //todo:加载更多 onLoad: () async { print('加载更多'); onLoadMore(); }, )), ) ], ), color: Colors.white, ), ); } //调用接口 Future<Null> searchHttp() async { pois = []; PeripheralInformationEntity locationInformationEntity = await searchForHttp(1); if (locationInformationEntity.status == "1") { print('请求成功'); pageIndex = 1; pois = locationInformationEntity.pois; int total = int.parse(locationInformationEntity.count); //整页 if (total % pageSize == 0) { pages = (total / pageSize).floor(); } else { pages = (total / pageSize).floor() + 1; } setState(() { }); } else { Fluttertoast.showToast(msg: "请求失败"); } } //加载更多 Future<Null> onLoadMore() async { if (pageIndex < pages) { PeripheralInformationEntity locationInformationEntity = await searchForHttp(pageIndex + 1); if (locationInformationEntity.status == "1") { print('请求成功'); pageIndex++; pois.addAll(locationInformationEntity.pois); } else { Fluttertoast.showToast(msg: "请求失败"); } } else { Fluttertoast.showToast(msg: "没有更多数据了"); } } //高德接口获取周边数据---不使用插件 aroundHttp() async { PeripheralInformationEntity locationInformationEntity = await aroundForHttp(); if (locationInformationEntity.status == "1") { print('请求成功'); pois = locationInformationEntity.pois; int total = int.parse(locationInformationEntity.count); //总数量 //算页数 if (total % pageSize == 0) { pages = (total / pageSize).floor(); } else { pages = (total / pageSize).floor() + 1; } } else { Fluttertoast.showToast(msg: "没有更多数据了"); } } //高德接口搜索---不使用插件 Future<PeripheralInformationEntity> searchForHttp(pageIndex) async { String BaseUrl = "https://restapi.amap.com/v3/place/text"; Map<String, dynamic> map = Map(); map["key"] = androidAMapKey; map["keywords"] = searchController.text; map["city"] = currentAddressInfo.city; //搜索的城市 map["offset"] = pageSize; //每页记录数据 map["page"] = pageIndex; //每页记录数据 map["citylimit"] = cityLimit; //仅返回指定城市数据 Response resp = await Http.getInstance() .dio .get( BaseUrl, queryParameters: map, ) .catchError((e) { print(e); }); PeripheralInformationEntity baseBean = PeripheralInformationEntity.fromJson(resp.data); return baseBean; } //高德接口获取当前位置周边信息---不使用插件 Future<PeripheralInformationEntity> aroundForHttp() async { String BaseUrl = "https://restapi.amap.com/v3/place/around"; Map<String, dynamic> map = Map(); map["key"] = androidAMapKey; map["keywords"] = searchController.text; map["city"] = currentAddressInfo.city; //搜索的城市 map["location"] = "${currentAddressInfo.longitude},${currentAddressInfo.latitude}"; //中心点坐标 经度和纬度用","分割,经度在前,纬度在后,经纬度小数点后不得超过6位 map["offset"] = pageSize; //每页记录数据 map["page"] = pageIndex; //每页记录数据 map["citylimit"] = cityLimit; //仅返回指定城市数据 Response resp = await Http.getInstance().dio.get( BaseUrl, queryParameters: map, ).catchError((e) { print(e); }); PeripheralInformationEntity baseBean = PeripheralInformationEntity.fromJson(resp.data); return baseBean; } }
peripheral_information_entity.dart
class PeripheralInformationEntity { PeripheralInformationSuggestion suggestion; String count; String infocode; List<PeripheralInformationPoi> pois; String status; String info; PeripheralInformationEntity({this.suggestion, this.count, this.infocode, this.pois, this.status, this.info}); PeripheralInformationEntity.fromJson(Map<String, dynamic> json) { suggestion = json['suggestion'] != null ? new PeripheralInformationSuggestion.fromJson(json['suggestion']) : null; count = json['count']; infocode = json['infocode']; if (json['pois'] != null) { pois = new List<PeripheralInformationPoi>();(json['pois'] as List).forEach((v) { pois.add(new PeripheralInformationPoi.fromJson(v)); }); } status = json['status']; info = json['info']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); if (this.suggestion != null) { data['suggestion'] = this.suggestion.toJson(); } data['count'] = this.count; data['infocode'] = this.infocode; if (this.pois != null) { data['pois'] = this.pois.map((v) => v.toJson()).toList(); } data['status'] = this.status; data['info'] = this.info; return data; } } class PeripheralInformationSuggestion { List<Null> keywords; List<Null> cities; PeripheralInformationSuggestion({this.keywords, this.cities}); PeripheralInformationSuggestion.fromJson(Map<String, dynamic> json) { if (json['keywords'] != null) { keywords = new List<Null>(); } if (json['cities'] != null) { cities = new List<Null>(); } } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); if (this.keywords != null) { data['keywords'] = []; } if (this.cities != null) { data['cities'] = []; } return data; } } class PeripheralInformationPoi { List<Null> parent; dynamic address; List<Null> distance; PeripheralInformationPoisBizExt bizExt; String pname; List<Null> importance; List<Null> bizType; String cityname; String type; List<PeripheralInformationPoisPhoto> photos; String typecode; String shopinfo; List<Null> poiweight; List<Null> childtype; String adname; String name; String location; String tel; List<Null> shopid; String id; PeripheralInformationPoi({this.parent, this.address, this.distance, this.bizExt, this.pname, this.importance, this.bizType, this.cityname, this.type, this.photos, this.typecode, this.shopinfo, this.poiweight, this.childtype, this.adname, this.name, this.location, this.tel, this.shopid, this.id}); PeripheralInformationPoi.fromJson(Map<String, dynamic> json) { if (json['parent'] != null) { parent = new List<Null>(); } address = json['address']; if (json['distance'] != null) { distance = new List<Null>(); } bizExt = json['biz_ext'] != null ? new PeripheralInformationPoisBizExt.fromJson(json['biz_ext']) : null; pname = json['pname']; cityname = json['cityname']; type = json['type']; typecode = json['typecode']; shopinfo = json['shopinfo']; adname = json['adname']; name = json['name']; location = json['location']; id = json['id']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); if (this.parent != null) { data['parent'] = []; } data['address'] = this.address; if (this.distance != null) { data['distance'] = []; } if (this.bizExt != null) { data['biz_ext'] = this.bizExt.toJson(); } data['pname'] = this.pname; if (this.importance != null) { data['importance'] = []; } if (this.bizType != null) { data['biz_type'] = []; } data['cityname'] = this.cityname; data['type'] = this.type; if (this.photos != null) { data['photos'] = this.photos.map((v) => v.toJson()).toList(); } data['typecode'] = this.typecode; data['shopinfo'] = this.shopinfo; if (this.poiweight != null) { data['poiweight'] = []; } if (this.childtype != null) { data['childtype'] = []; } data['adname'] = this.adname; data['name'] = this.name; data['location'] = this.location; data['tel'] = this.tel; if (this.shopid != null) { data['shopid'] = []; } data['id'] = this.id; return data; } } class PeripheralInformationPoisBizExt { List<Null> cost; String rating; PeripheralInformationPoisBizExt({this.cost, this.rating}); PeripheralInformationPoisBizExt.fromJson(Map<String, dynamic> json) { if (json['cost'] != null) { cost = new List<Null>(); } } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); if (this.cost != null) { data['cost'] = []; } data['rating'] = this.rating; return data; } } class PeripheralInformationPoisPhoto { List<Null> provider; List<Null> title; String url; PeripheralInformationPoisPhoto({this.provider, this.title, this.url}); PeripheralInformationPoisPhoto.fromJson(Map<String, dynamic> json) { if (json['provider'] != null) { provider = new List<Null>(); } if (json['title'] != null) { title = new List<Null>(); } url = json['url']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); if (this.provider != null) { data['provider'] = []; } if (this.title != null) { data['title'] = []; } data['url'] = this.url; return data; } }
请求框架 http.dart
import 'dart:io'; import 'package:carbutlerflutter/constant/constant.dart'; import 'package:dio/dio.dart'; import 'config.dart'; class Config { // String base_url = "http://chenhongye1.qicp.io:55118"; String base_url = "https://restapi.amap.com/v3/place/text"; int connectTimeout = 60000; int receiveTimeout = 60000; } /** * 通过网络请求工具 */ class Http{ static Http instance; static String token; Config _config = new Config(); Dio _dio; static Http getInstance(){ if(instance == null){ instance = new Http(); } return instance; } Http(){ // 初始化 Options _dio = new Dio(); _dio.options.baseUrl =_config.base_url; _dio.options.connectTimeout = _config.connectTimeout; _dio.options.receiveTimeout = _config.receiveTimeout; //https证书校验 (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) { client.badCertificateCallback=(X509Certificate cert, String host, int port){ return true; }; }; _dio.interceptors.add(InterceptorsWrapper( onRequest:(RequestOptions options){ // 在请求被发送之前做一些事情 Map<String,dynamic> _headers = options.headers??{}; print("\n================== 请求数据 =========================="); print("url = ${options.uri.toString()}"); print("headers = ${options.headers}"); return options; //continue // 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`对象或返回`dio.resolve(data)`。 // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义数据data. // // 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,或返回`dio.reject(errMsg)`, // 这样请求将被中止并触发异常,上层catchError会被调用。 }, onResponse:(Response response) { // 在返回响应数据之前做一些预处理 print("================== 响应数据 =========================="); print("statusCode:${response.statusCode}"); print("response.data:${response.data}"); return response; }, onError: (DioError e) { // 当请求失败时做一些预处理 return e;//continue } )); } Dio get dio { return _dio; } }
谢谢观看 oVo
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。