Android高德地圖API實現POI搜索

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

相關文章
相關標籤/搜索