天天看點

基于百度地圖sdk的地圖app開發(五)——poi檢索1、在布局檔案中添加輸入框2、 建立POI檢索執行個體3、  建立POI檢索監聽器接收檢索結果4 設定檢索監聽器5、 發起檢索6、 顯示搜尋結果7 、當點選搜尋結果清單之外區域時隐藏結果清單

這是基于百度地圖sdk的地圖app開發系列部落格第五篇

代碼倉庫位置:https://github.com/YanhuiLu89/lmap.git

上一篇 基于百度地圖sdk的地圖app開發(四)——顯示地圖定位

下一篇 基于百度地圖sdk的地圖app開發(六)——路線規劃

因為本人是做C++開發,android和java都不熟,這方面知識有說錯或者不好的習慣,歡迎賜較。

官方參考文檔POI檢索

POI(Point of Interest),即“興趣點”。在地理資訊系統中,一個POI可以是一棟房子、一個景點、一個郵筒或者一個公交站等。

poi檢索分為城市内關鍵字檢索和周邊檢索,其實作方式差不多,這裡隻實作城市内關鍵字檢索,周邊檢索略。

關鍵字檢索适用于在某個城市内搜尋某個名稱相關的POI,例如:查找“北京市”的“小吃”。

1、在布局檔案中添加輸入框

在地圖最上方(原先地圖模式按鈕的上方)添加EditText控件

添加後xml檔案内容如下(注意:android:imeOptions="actionSearch"這個屬性,這樣設定鍵盤預設的換行鍵顯示為搜尋)

<EditText
        android:id="@+id/inputText"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="50dp"
        android:background="@android:drawable/editbox_dropdown_dark_frame"
        android:ems="10"
        android:hint="請輸入要搜尋的内容"
        android:imeOptions="actionSearch"
        android:inputType="text"
        android:textColor="@color/white"
        app:layout_anchorGravity="top" />

    <ImageButton
        android:id="@+id/mapTypeBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        app:layout_anchorGravity="top"
        app:srcCompat="@android:drawable/ic_dialog_map" />
           

效果圖如下

基于百度地圖sdk的地圖app開發(五)——poi檢索1、在布局檔案中添加輸入框2、 建立POI檢索執行個體3、  建立POI檢索監聽器接收檢索結果4 設定檢索監聽器5、 發起檢索6、 顯示搜尋結果7 、當點選搜尋結果清單之外區域時隐藏結果清單

2、 建立POI檢索執行個體

在MainActivity增加PoiSearch成員變量

private PoiSearch mPoiSearch=null;
           

在onCreate函數中建立poi檢索執行個體

//建立poi檢索執行個體
        mPoiSearch = PoiSearch.newInstance();
        
           

3、  建立POI檢索監聽器接收檢索結果

這裡暫時空實作,後面步驟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) {

        }
    };
           

4 設定檢索監聽器

//設定監聽器
        mPoiSearch.setOnGetPoiSearchResultListener(poiSearchListener);
           

5、 發起檢索

在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);
           

6、 顯示搜尋結果

6.1 layout中添加顯示搜尋結果的布局檔案poi_item.xml

内容如下

<?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">

    <TextView
        android:id="@+id/poiname"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView"
        android:textColor="@color/white"
        android:textSize="24sp" />

    <TextView
        android:id="@+id/poiaddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView"
        android:textColor="@color/white"
        android:textSize="14sp" />
</LinearLayout>
           

6.2、 activity_main.xml中添加listView控件

代碼如下

<ListView
        android:id="@+id/searchResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="120dp"
        android:background="@color/material_on_background_emphasis_high_type"
        android:visibility="gone" />
           

6.3、 建立PoiAdapter擴充卡類

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<PoiInfo> {
    private int resourceId;
    public PoiAdapter(@NonNull Context context, int resource, @NonNull List<PoiInfo> 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;
    }
}
           

6.4、 在POI檢索監聽器往listView中填充内容

在步驟3中建立的POI檢索監聽器的onGetPoiResult函數中添加以下代碼來顯示搜尋結果 

該部分除了要顯示目前頁搜尋結果外,還在 listView的滾動監聽函數中實作了,當滾動到底部時加載下一頁搜尋結果的功能

public void onGetPoiResult(PoiResult poiResult) {
            //顯示搜尋結果
            List<PoiInfo> 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));
                            }
                        }
                    }
                }
           

最後搜尋結果實作效果如下

基于百度地圖sdk的地圖app開發(五)——poi檢索1、在布局檔案中添加輸入框2、 建立POI檢索執行個體3、  建立POI檢索監聽器接收檢索結果4 設定檢索監聽器5、 發起檢索6、 顯示搜尋結果7 、當點選搜尋結果清單之外區域時隐藏結果清單

7 、當點選搜尋結果清單之外區域時隐藏結果清單

最後,重寫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);
 }