实现效果图以下:
java
导入高德地图的搜索服务包到工程的libs目录中,并配置好权限与用户KEY。
权限以下:android
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
用户KEY配置以下:git
<meta-data android:name="com.amap.api.v2.apikey" android:value="这里填你的KEY"/>
建立activity_main.xml布局文件以下,由于要实现用户输入直接就显示数据,因此就没用到搜索按钮。api
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/search_edit" android:layout_width="match_parent" android:layout_height="wrap_content"/> <ListView android:id="@+id/search_list" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </LinearLayout>
建立address_item.xml布局文件以下,用于ListView中每个Item布局。异步
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="20dp" > <TextView android:id="@+id/item_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="标题" android:textSize="20sp"/> <TextView android:id="@+id/item_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="内容" android:textColor="#FF4A4A4A"/> </LinearLayout>
建立AddressBean实体类,代码以下ide
public class AddressBean { private double longitude;//经度 private double latitude;//纬度 private String title;//信息标题 private String text;//信息内容 public AddressBean(double lon, double lat, String title, String text){ this.longitude = lon; this.latitude = lat; this.title = title; this.text = text; } public double getLongitude() { return longitude; } public double getLatitude() { return latitude; } public String getTitle() { return title; } public String getText(){ return text; } }
建立SearchAdapter数据适配器类,代码以下:布局
public class SearchAdapter extends BaseAdapter{ private List<AddressBean> data; private LayoutInflater li; public SearchAdapter(Context context){ li = LayoutInflater.from(context); } /** * 设置数据集 * @param data */ public void setData(List<AddressBean> data){ this.data = data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh = null; if(convertView == null){ vh = new ViewHolder(); convertView = li.inflate(R.layout.address_item, null); vh.title = (TextView) convertView.findViewById(R.id.item_title); vh.text = (TextView) convertView.findViewById(R.id.item_text); convertView.setTag(vh); }else{ vh = (ViewHolder) convertView.getTag(); } vh.title.setText(data.get(position).getTitle()); vh.text.setText(data.get(position).getText()); return convertView; } private class ViewHolder{ public TextView title; public TextView text; } }
这里会提供方法setData()用于动态更新数据集。this
建立InputTask类,封装PoiSearch的搜索服务,并与Adapter进行绑定。code
public class InputTask implements OnPoiSearchListener { private static InputTask mInstance; private SearchAdapter mAdapter; private PoiSearch mSearch; private Context mContext; private InputTask(Context context, SearchAdapter adapter){ this.mContext = context; this.mAdapter = adapter; } /** * 获取实例 * @param context 上下文 * @param adapter 数据适配器 * @return */ public static InputTask getInstance(Context context, SearchAdapter adapter){ if(mInstance == null){ synchronized (InputTask.class) { if(mInstance == null){ mInstance = new InputTask(context, adapter); } } } return mInstance; } /** * 设置数据适配器 * @param adapter */ public void setAdapter(SearchAdapter adapter){ this.mAdapter = adapter; } /** * POI搜索 * @param key 关键字 * @param city 城市 */ public void onSearch(String key, String city){ //POI搜索条件 PoiSearch.Query query = new PoiSearch.Query(key, "", city); mSearch = new PoiSearch(mContext, query); //设置异步监听 mSearch.setOnPoiSearchListener(this); //查询POI异步接口 mSearch.searchPOIAsyn(); } /** * 异步搜索回调 */ @Override public void onPoiSearched(PoiResult poiResult, int rCode) { if(rCode == 0 && poiResult != null){ ArrayList<AddressBean> data = new ArrayList<AddressBean>(); ArrayList<PoiItem> items = poiResult.getPois(); for(PoiItem item : items){ //获取经纬度对象 LatLonPoint llp = item.getLatLonPoint(); double lon = llp.getLongitude(); double lat = llp.getLatitude(); //获取标题 String title = item.getTitle(); //获取内容 String text = item.getSnippet(); data.add(new AddressBean(lon, lat, title, text)); } mAdapter.setData(data); mAdapter.notifyDataSetChanged(); } } }
使用PoiSearch.Query定义搜索条件,构造方法有三个参数分别是:搜索关键字、POI类别、城市(地区)。
其中多个关键字用“|”分割,POI类别能够为""空字符串表明不区分类别,城市能够为""空字符串表明检索全部城市。
在搜索到结果回调的时候使用notifyDataSetChanged()更新数据适配器,实现数据动态更新。xml
建立MainAty类,代码以下:
public class MainAty extends Activity implements TextWatcher, OnItemClickListener{ private static final String TAG = "MainAty"; private EditText edit; private ListView lv; private SearchAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView(){ edit = (EditText) findViewById(R.id.search_edit); lv = (ListView) findViewById(R.id.search_list); edit.addTextChangedListener(this); mAdapter = new SearchAdapter(this); lv.setAdapter(mAdapter); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { InputTask.getInstance(this, mAdapter).onSearch(s.toString(), ""); } @Override public void afterTextChanged(Editable s) { } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //Item点击事件处理 } }
实现TextWatcher,并重写onTextChanged方法监听输入框数据的变化,从而实现实时更新数据。