这是基于百度地图sdk的地图app开发系列博客第五篇
代码仓库位置:https://github.com/YanhuiLu89/lmap.git
上一篇 基于百度地图sdk的地图app开发(四)——显示地图定位
因为本人是做C++开发,android和java都不熟,这方面知识有说错或者不好的习惯,欢迎赐较。
官方参考文档POI检索
POI(Point of Interest),即“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个景点、一个邮筒或者一个公交站等。
poi检索分为城市内关键字检索和周边检索,其实现方式差不多,这里只实现城市内关键字检索,周边检索略。
关键字检索适用于在某个城市内搜索某个名称相关的POI,例如:查找“北京市”的“小吃”。
在地图最上方(原先地图模式按钮的上方)添加EditText控件
添加后xml文件内容如下(注意:android:imeOptions="actionSearch"这个属性,这样设置键盘默认的换行键显示为搜索)
效果图如下
在MainActivity增加PoiSearch成员变量
private PoiSearch mPoiSearch=null;
在onCreate函数中创建poi检索实例
//创建poi检索实例
mPoiSearch = PoiSearch.newInstance();
这里暂时空实现,后面步骤6,显示搜索结果时填到相应布局中
//创建poi检索监听器
OnGetPoiSearchResultListener poiSearchListener = new OnGetPoiSearchResultListener() {
@Override
public void onGetPoiResult(PoiResult poiResult) {
}
@Override
public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {
}
@Override
public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
}
//废弃
@Override
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
}
};
//设置监听器
mPoiSearch.setOnGetPoiSearchResultListener(poiSearchListener);
在EditText控件的OnEditorActionListener监听器中调用searchInCity函数发起检索,代码如下
//获得检索输入框控件
mInputText=findViewById(R.id.inputText);
mInputText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean ret=false;
if(actionId== EditorInfo.IME_ACTION_SEARCH)
{
String city=mCurLocation.getCity();
String keyWord=v.getText().toString();
ret=mPoiSearch.searchInCity(new PoiCitySearchOption()
.city(city)
.keyword(keyWord)
.pageNum(0));
//搜索后隐藏键盘
InputMethodManager imum=(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
View view=getWindow().peekDecorView();
if(view!=null)
{
imum.hideSoftInputFromWindow(view.getWindowToken(),0);
}
}
return ret;
}
});
注意:如果mCurLocation.getCity()返回null,那是因为在配置定位设置时,少了一步,默认是不开启获取当前位置的,需要加下面一行代码(定位详细配置参考上一篇基于百度地图sdk的地图app开发(四)——显示地图定位 的第4部分“4 通过LocationClient发起定位”代码)
option.setIsNeedAddress(true);
内容如下
代码如下
package com.example.lmap;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.baidu.mapapi.search.core.PoiInfo;
import java.util.List;
public class PoiAdapter extends ArrayAdapter {
private int resourceId;
public PoiAdapter(@NonNull Context context, int resource, @NonNull List objects) {
super(context, resource, objects);
resourceId=resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
PoiInfo poi=getItem(position);
View view= LayoutInflater.from(getContext()).inflate(resourceId,null);
TextView name=view.findViewById(R.id.poiname);
TextView address=view.findViewById(R.id.poiaddress);
name.setText(poi.name);
address.setText(poi.address);
return view;
}
}
在步骤3中创建的POI检索监听器的onGetPoiResult函数中添加以下代码来显示搜索结果
该部分除了要显示当前页搜索结果外,还在 listView的滚动监听函数中实现了,当滚动到底部时加载下一页搜索结果的功能
public void onGetPoiResult(PoiResult poiResult) {
//显示搜索结果
List poiList=poiResult.getAllPoi();
PoiAdapter adapter=new PoiAdapter(MainActivity.this,R.layout.poi_item,poiList);
ListView listView=findViewById(R.id.searchResult);
listView.setAdapter(adapter);
listView.setVisibility(View.VISIBLE);
//当滑动到底部时加载更多搜索结果
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
// 判断是否滚动到底部
if (view.getLastVisiblePosition() == view.getCount() - 1) {
//加载更多
int curPage=poiResult.getCurrentPageNum();
int totalPage=poiResult.getTotalPageNum();
if(curPage< totalPage)
{
poiResult.setCurrentPageNum(curPage+1);
String city=mCurLocation.getCity();
TextView textV=findViewById(R.id.inputText);
String keyWord=textV.getText().toString();
mPoiSearch.searchInCity(new PoiCitySearchOption()
.city(city)
.keyword(keyWord)
.pageNum(curPage+1));
}
}
}
}
最后搜索结果实现效果如下
最后,重写dispatchTouchEvent函数,实现当点击索结果列表之外区域时隐藏结果列表
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
ListView listView = findViewById(R.id.searchResult);
int left = listView.getLeft(), top = listView.getTop(), right = left + listView.getWidth(), bottom = top + listView.getHeight();
if (ev.getX() < left || ev.getX() > right || ev.getY() < top || ev.getY() > bottom)//点击搜索结果列表之外区域,隐藏搜索结果列表
listView.setVisibility(View.GONE);
}
return super.dispatchTouchEvent(ev);
}