首先我们看一下最终效果
首先是仿滴滴出行的不会跟随地图移动的一个Marker
当停止移动地图时搜索周边数据
点击周边数据改变地图中心点
关键字搜索
用到的大部分都是上一篇博客的知识点,接下来我们开始做
首先是主界面的代码
public class MainActivity extends Activity implements AMap.OnMapTouchListener, AMap.OnMapLoadedListener {
public static final int SEARCH_CODE = 1;
MapView mMapView;
AMap aMap;
ListView listView;
MainAdapter mainAdapter;
//中心点Marker对象
Marker marker;
//构造 GeocodeSearch 对象
GeocodeSearch geocoderSearch;
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
public AMapLocationClientOption mLocationOption = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onLocationChanged(AMapLocation amapLocation) {
if (amapLocation != null) {
if (amapLocation.getErrorCode() == 0) {
//获得经纬度对象
LatLonPoint latLonPoint = new LatLonPoint(amapLocation.getLatitude(), amapLocation.getLongitude());
//移动到当前定位中心点
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
convertToLatLng(latLonPoint), 15));
gerGeocodeSearch(latLonPoint);
} else {
//显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
Log.e("AmapError", "location Error, ErrCode:"
+ amapLocation.getErrorCode() + ", errInfo:"
+ amapLocation.getErrorInfo());
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
initView(savedInstanceState);
}
/**
* 把LatLng对象转化为LatLonPoint对象
*/
public static LatLonPoint convertToLatLonPoint(LatLng latlon) {
return new LatLonPoint(latlon.latitude, latlon.longitude);
}
/**
* 把LatLonPoint对象转化为LatLon对象
*/
public static LatLng convertToLatLng(LatLonPoint latLonPoint) {
return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());
}
/**
* 初始化
*
* @param savedInstanceState
*/
private void initView(Bundle savedInstanceState) {
mMapView = (MapView) findViewById(R.id.mv);
listView = (ListView) findViewById(R.id.lv);
mMapView.onCreate(savedInstanceState);
aMap = mMapView.getMap();
aMap.setOnMapTouchListener(this);
aMap.setOnMapLoadedListener(this);
initLocation();
}
/**
* 初始化定位
*/
private void initLocation() {
mLocationClient = new AMapLocationClient(this);
mLocationClient.setLocationListener(mLocationListener);
//初始化定位参数
mLocationOption = new AMapLocationClientOption();
//设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置是否返回地址信息(默认返回地址信息)
mLocationOption.setNeedAddress(true);
//设置是否只定位一次,默认为false
mLocationOption.setOnceLocation(true);
//设置是否强制刷新WIFI,默认为强制刷新
mLocationOption.setWifiActiveScan(true);
//设置是否允许模拟位置,默认为false,不允许模拟位置
mLocationOption.setMockEnable(false);
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView.onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView.onPause (),实现地图生命周期管理
mMapView.onPause();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),实现地图生命周期管理
mMapView.onSaveInstanceState(outState);
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
//销毁定位客户端,同时销毁本地定位服务。
mLocationClient.onDestroy();
}
@Override
public void onTouch(MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
//判断手指抬起就去搜索周边信息
gerGeocodeSearch(null);
}
}
/**
* 进行逆地理搜索
*/
private void gerGeocodeSearch(LatLonPoint latLng) {
if (geocoderSearch == null) {
geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(getRegeocodeAddress);
}
// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
RegeocodeQuery query = new RegeocodeQuery(latLng == null ? convertToLatLonPoint(marker.getPosition()) : latLng, 200, GeocodeSearch.AMAP);
//发起请求
geocoderSearch.getFromLocationAsyn(query);
}
/**
* 逆地理搜索回调
*/
GeocodeSearch.OnGeocodeSearchListener getRegeocodeAddress = new GeocodeSearch.OnGeocodeSearchListener() {
@Override
public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
//判断请求是否成功(1000为成功,其他为失败)
if (i == 1000) {
if (regeocodeResult != null && regeocodeResult.getRegeocodeAddress() != null && regeocodeResult.getRegeocodeAddress().getFormatAddress() != null) {
//判断是否非空,非空就实例化,不为空就刷新数据
if (mainAdapter == null) {
listView.setAdapter(mainAdapter = new MainAdapter(MainActivity.this, regeocodeResult, itemClicklistener));
} else {
mainAdapter.refresh(regeocodeResult);
}
}
}
}
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
}
};
/**
* 移动位置结果点击回调
*/
MainAdapter.onItemClicklistener itemClicklistener = new MainAdapter.onItemClicklistener() {
@Override
public void callBack(PoiItem poiItem) {
//移动到选中的位置
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
convertToLatLng(poiItem.getLatLonPoint()), 15));
}
};
/**
* 搜索按钮点击
*
* @param view
*/
public void search(View view) {
//跳转到搜索界面
Intent intent = new Intent(MainActivity.this, SearchActivity.class);
startActivityForResult(intent, SEARCH_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SEARCH_CODE) {
String lat = data.getStringExtra(SearchActivity.SEARCH_RESULT_LAT);
String lng = data.getStringExtra(SearchActivity.SEARCH_RESULT_LNG);
if (null != lat && null != lng && !lat.isEmpty() && !lng.isEmpty()) {
LatLonPoint latLonPoint = new LatLonPoint(Double.parseDouble(lat), Double.parseDouble(lng));
//移动到中心点
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
convertToLatLng(latLonPoint), 15));
//搜索周边数据
gerGeocodeSearch(latLonPoint);
}
}
}
}
@Override
public void onMapLoaded() {
// MapView 是GlSurfaceView 有对应的getWidth和getHeight方法,可以获取view的宽高,可以在onMapLoaded之后获取,这样得到的是准确的,提前获取有可能是0。
marker = aMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.location_marker)));
//设置Marker在屏幕上,不跟随地图移动
marker.setPositionByPixels(mMapView.getWidth() / 2, mMapView.getHeight() / 2);
}
}
主界面的Adapter
public class MainAdapter extends BaseAdapter {
Context mContext;
RegeocodeResult regeocodeResult;
onItemClicklistener itemClicklistener;
public MainAdapter(Context mContext, RegeocodeResult regeocodeResult, onItemClicklistener itemClicklistener) {
this.mContext = mContext;
this.regeocodeResult = regeocodeResult;
this.itemClicklistener = itemClicklistener;
}
public interface onItemClicklistener {
void callBack(PoiItem poiItem);
}
/**
* 更新数据
*/
public void refresh(RegeocodeResult regeocodeResult) {
this.regeocodeResult = regeocodeResult;
notifyDataSetChanged();
}
@Override
public int getCount() {
return regeocodeResult.getRegeocodeAddress().getPois().size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.listitem_main, parent, false);
} else {
view = convertView;
}
TextView textView = (TextView) view.findViewById(R.id.item_main_text);
textView.setText(regeocodeResult.getRegeocodeAddress().getPois().get(position).getTitle());
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemClicklistener.callBack(regeocodeResult.getRegeocodeAddress().getPois().get(position));
}
});
return view;
}
}
再就是搜索界面
public class SearchActivity extends Activity implements TextWatcher {
public static final String SEARCH_RESULT_LAT = "search_result_latitude";
public static final String SEARCH_RESULT_LNG = "search_result_longitude";
EditText et;
ListView listView;
SearchAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_activity);
initView();
}
/**
* 初始化View并绑定监听
*/
private void initView() {
et = (EditText) findViewById(R.id.et_content);
listView = (ListView) findViewById(R.id.search_lv);
et.addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String content = et.getText().toString().trim();
//判断非空
if (null != content && !content.isEmpty()) {
//通过Query设置搜索条件,第一个参数为搜索内容,第二个参数为搜索类型,第三个参数为搜索范围(空字符串代表全国)。
PoiSearch.Query query = new PoiSearch.Query(content, "", "");
PoiSearch poiSearch = new PoiSearch(SearchActivity.this, query);
poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
@Override
public void onPoiSearched(PoiResult poiResult, int errcode) {
//判断搜索成功
if (errcode == 1000) {
if (null != poiResult && poiResult.getPois().size() > 0) {
if (adapter == null) {
listView.setAdapter(adapter = new SearchAdapter(SearchActivity.this, poiResult, onItemClicklistener));
} else {
adapter.refresh(poiResult);
}
}
}
}
@Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
}
});
poiSearch.searchPOIAsyn();
}
}
/**
* 搜索结果点击回调
*/
SearchAdapter.onItemClicklistener onItemClicklistener = new SearchAdapter.onItemClicklistener() {
@Override
public void callBack(PoiItem poiItem) {
Intent data = new Intent();
data.putExtra(SEARCH_RESULT_LAT, String.valueOf(poiItem.getLatLonPoint().getLatitude()));
data.putExtra(SEARCH_RESULT_LNG, String.valueOf(poiItem.getLatLonPoint().getLongitude()));
setResult(RESULT_OK, data);
finish();
}
};
}
搜索界面Adapter
public class SearchAdapter extends BaseAdapter {
Context mContext;
PoiResult result;
onItemClicklistener onItemClicklistener;
public SearchAdapter(Context mContext, PoiResult result, onItemClicklistener onItemClicklistener) {
this.mContext = mContext;
this.result = result;
this.onItemClicklistener = onItemClicklistener;
}
public interface onItemClicklistener {
void callBack(PoiItem poiItem);
}
/**
* 更新数据源
*/
public void refresh(PoiResult result) {
this.result = result;
notifyDataSetChanged();
}
@Override
public int getCount() {
return result.getPois().size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.listitem_main, parent, false);
} else {
view = convertView;
}
TextView textView = (TextView) view.findViewById(R.id.item_main_text);
textView.setText(result.getPois().get(position).getTitle());
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClicklistener.callBack(result.getPois().get(position));
}
});
return view;
}
}
做法基本是这样,有什么不懂的可以在下面留言,还有一点需要注意的是关键字搜索的结果有些地方是没有经纬度的,所以返回之前需要判断,如果出现空指针现象,请在搜索结果点击回调之前判断非空