實現效果圖以下:
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方法監聽輸入框數據的變化,從而實現實時更新數據。