高德地图实战训练之仿加菲派地图选址

本文介绍了一款仿滴滴出行的地图应用程序开发过程,包括如何创建不随地图移动的标记、搜索周边地点、响应用户触摸事件等功能,并详细展示了主界面、适配器及搜索界面的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先我们看一下最终效果
这里写图片描述
这里写图片描述
首先是仿滴滴出行的不会跟随地图移动的一个Marker
当停止移动地图时搜索周边数据
点击周边数据改变地图中心点
关键字搜索

用到的大部分都是上一篇博客的知识点,接下来我们开始做
首先是主界面的代码

public class MainActivity extends Activity implements AMap.OnMapTouchListener, AMap.OnMapLoadedListener {
    public static final int SEARCH_CODE = 1;
    MapView mMapView;
    AMap aMap;
    ListView listView;
    MainAdapter mainAdapter;
    //中心点Marker对象
    Marker marker;
    //构造 GeocodeSearch 对象
    GeocodeSearch geocoderSearch;
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    public AMapLocationClientOption mLocationOption = null;
    //声明定位回调监听器
    public AMapLocationListener mLocationListener = new AMapLocationListener() {
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public void onLocationChanged(AMapLocation amapLocation) {
            if (amapLocation != null) {
                if (amapLocation.getErrorCode() == 0) {
                    //获得经纬度对象
                    LatLonPoint latLonPoint = new LatLonPoint(amapLocation.getLatitude(), amapLocation.getLongitude());
                    //移动到当前定位中心点
                    aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                            convertToLatLng(latLonPoint), 15));
                    gerGeocodeSearch(latLonPoint);
                } else {
                    //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
                    Log.e("AmapError", "location Error, ErrCode:"
                            + amapLocation.getErrorCode() + ", errInfo:"
                            + amapLocation.getErrorInfo());
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        initView(savedInstanceState);
    }


    /**
     * 把LatLng对象转化为LatLonPoint对象
     */
    public static LatLonPoint convertToLatLonPoint(LatLng latlon) {
        return new LatLonPoint(latlon.latitude, latlon.longitude);
    }

    /**
     * 把LatLonPoint对象转化为LatLon对象
     */
    public static LatLng convertToLatLng(LatLonPoint latLonPoint) {
        return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());
    }


    /**
     * 初始化
     *
     * @param savedInstanceState
     */
    private void initView(Bundle savedInstanceState) {
        mMapView = (MapView) findViewById(R.id.mv);
        listView = (ListView) findViewById(R.id.lv);
        mMapView.onCreate(savedInstanceState);
        aMap = mMapView.getMap();
        aMap.setOnMapTouchListener(this);
        aMap.setOnMapLoadedListener(this);
        initLocation();
    }

    /**
     * 初始化定位
     */
    private void initLocation() {
        mLocationClient = new AMapLocationClient(this);
        mLocationClient.setLocationListener(mLocationListener);
        //初始化定位参数
        mLocationOption = new AMapLocationClientOption();
        //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置是否返回地址信息(默认返回地址信息)
        mLocationOption.setNeedAddress(true);
        //设置是否只定位一次,默认为false
        mLocationOption.setOnceLocation(true);
        //设置是否强制刷新WIFI,默认为强制刷新
        mLocationOption.setWifiActiveScan(true);
        //设置是否允许模拟位置,默认为false,不允许模拟位置
        mLocationOption.setMockEnable(false);
        //给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        //启动定位
        mLocationClient.startLocation();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView.onResume (),实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView.onPause (),实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),实现地图生命周期管理
        mMapView.onSaveInstanceState(outState);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
        //销毁定位客户端,同时销毁本地定位服务。
        mLocationClient.onDestroy();
    }

    @Override
    public void onTouch(MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
            //判断手指抬起就去搜索周边信息
            gerGeocodeSearch(null);
        }
    }

    /**
     * 进行逆地理搜索
     */
    private void gerGeocodeSearch(LatLonPoint latLng) {
        if (geocoderSearch == null) {
            geocoderSearch = new GeocodeSearch(this);
            geocoderSearch.setOnGeocodeSearchListener(getRegeocodeAddress);
        }
        // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
        RegeocodeQuery query = new RegeocodeQuery(latLng == null ? convertToLatLonPoint(marker.getPosition()) : latLng, 200, GeocodeSearch.AMAP);
        //发起请求
        geocoderSearch.getFromLocationAsyn(query);
    }

    /**
     * 逆地理搜索回调
     */
    GeocodeSearch.OnGeocodeSearchListener getRegeocodeAddress = new GeocodeSearch.OnGeocodeSearchListener() {
        @Override
        public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
            //判断请求是否成功(1000为成功,其他为失败)
            if (i == 1000) {
                if (regeocodeResult != null && regeocodeResult.getRegeocodeAddress() != null && regeocodeResult.getRegeocodeAddress().getFormatAddress() != null) {
                    //判断是否非空,非空就实例化,不为空就刷新数据
                    if (mainAdapter == null) {
                        listView.setAdapter(mainAdapter = new MainAdapter(MainActivity.this, regeocodeResult, itemClicklistener));
                    } else {
                        mainAdapter.refresh(regeocodeResult);
                    }
                }
            }
        }

        @Override
        public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

        }
    };
    /**
     * 移动位置结果点击回调
     */
    MainAdapter.onItemClicklistener itemClicklistener = new MainAdapter.onItemClicklistener() {
        @Override
        public void callBack(PoiItem poiItem) {
            //移动到选中的位置
            aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                    convertToLatLng(poiItem.getLatLonPoint()), 15));
        }
    };

    /**
     * 搜索按钮点击
     *
     * @param view
     */
    public void search(View view) {
        //跳转到搜索界面
        Intent intent = new Intent(MainActivity.this, SearchActivity.class);
        startActivityForResult(intent, SEARCH_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == SEARCH_CODE) {
                String lat = data.getStringExtra(SearchActivity.SEARCH_RESULT_LAT);
                String lng = data.getStringExtra(SearchActivity.SEARCH_RESULT_LNG);
                if (null != lat && null != lng && !lat.isEmpty() && !lng.isEmpty()) {
                    LatLonPoint latLonPoint = new LatLonPoint(Double.parseDouble(lat), Double.parseDouble(lng));
                    //移动到中心点
                    aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                            convertToLatLng(latLonPoint), 15));
                    //搜索周边数据
                    gerGeocodeSearch(latLonPoint);
                }
            }
        }
    }

    @Override
    public void onMapLoaded() {
        // MapView 是GlSurfaceView 有对应的getWidth和getHeight方法,可以获取view的宽高,可以在onMapLoaded之后获取,这样得到的是准确的,提前获取有可能是0。
        marker = aMap.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.location_marker)));
        //设置Marker在屏幕上,不跟随地图移动
        marker.setPositionByPixels(mMapView.getWidth() / 2, mMapView.getHeight() / 2);
    }
}

主界面的Adapter

public class MainAdapter extends BaseAdapter {
    Context mContext;
    RegeocodeResult regeocodeResult;
    onItemClicklistener itemClicklistener;

    public MainAdapter(Context mContext, RegeocodeResult regeocodeResult, onItemClicklistener itemClicklistener) {
        this.mContext = mContext;
        this.regeocodeResult = regeocodeResult;
        this.itemClicklistener = itemClicklistener;
    }

    public interface onItemClicklistener {
        void callBack(PoiItem poiItem);
    }

    /**
     * 更新数据
     */
    public void refresh(RegeocodeResult regeocodeResult) {
        this.regeocodeResult = regeocodeResult;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return regeocodeResult.getRegeocodeAddress().getPois().size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = null;
        if (convertView == null) {
            view = LayoutInflater.from(mContext).inflate(R.layout.listitem_main, parent, false);
        } else {
            view = convertView;
        }
        TextView textView = (TextView) view.findViewById(R.id.item_main_text);
        textView.setText(regeocodeResult.getRegeocodeAddress().getPois().get(position).getTitle());
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                itemClicklistener.callBack(regeocodeResult.getRegeocodeAddress().getPois().get(position));
            }
        });
        return view;
    }
}

再就是搜索界面

public class SearchActivity extends Activity implements TextWatcher {
    public static final String SEARCH_RESULT_LAT = "search_result_latitude";
    public static final String SEARCH_RESULT_LNG = "search_result_longitude";
    EditText et;
    ListView listView;
    SearchAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search_activity);
        initView();
    }

    /**
     * 初始化View并绑定监听
     */
    private void initView() {
        et = (EditText) findViewById(R.id.et_content);
        listView = (ListView) findViewById(R.id.search_lv);
        et.addTextChangedListener(this);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        String content = et.getText().toString().trim();
        //判断非空
        if (null != content && !content.isEmpty()) {
            //通过Query设置搜索条件,第一个参数为搜索内容,第二个参数为搜索类型,第三个参数为搜索范围(空字符串代表全国)。
            PoiSearch.Query query = new PoiSearch.Query(content, "", "");
            PoiSearch poiSearch = new PoiSearch(SearchActivity.this, query);
            poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
                @Override
                public void onPoiSearched(PoiResult poiResult, int errcode) {
                    //判断搜索成功
                    if (errcode == 1000) {
                        if (null != poiResult && poiResult.getPois().size() > 0) {
                            if (adapter == null) {
                                listView.setAdapter(adapter = new SearchAdapter(SearchActivity.this, poiResult, onItemClicklistener));
                            } else {
                                adapter.refresh(poiResult);
                            }
                        }
                    }
                }

                @Override
                public void onPoiItemSearched(PoiItem poiItem, int i) {

                }
            });
            poiSearch.searchPOIAsyn();
        }
    }

    /**
     * 搜索结果点击回调
     */
    SearchAdapter.onItemClicklistener onItemClicklistener = new SearchAdapter.onItemClicklistener() {
        @Override
        public void callBack(PoiItem poiItem) {
            Intent data = new Intent();
            data.putExtra(SEARCH_RESULT_LAT, String.valueOf(poiItem.getLatLonPoint().getLatitude()));
            data.putExtra(SEARCH_RESULT_LNG, String.valueOf(poiItem.getLatLonPoint().getLongitude()));
            setResult(RESULT_OK, data);
            finish();
        }

    };
}

搜索界面Adapter

public class SearchAdapter extends BaseAdapter {
    Context mContext;
    PoiResult result;
    onItemClicklistener onItemClicklistener;

    public SearchAdapter(Context mContext, PoiResult result, onItemClicklistener onItemClicklistener) {
        this.mContext = mContext;
        this.result = result;
        this.onItemClicklistener = onItemClicklistener;
    }

    public interface onItemClicklistener {
        void callBack(PoiItem poiItem);
    }

    /**
     * 更新数据源
     */
    public void refresh(PoiResult result) {
        this.result = result;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return result.getPois().size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = null;
        if (convertView == null) {
            view = LayoutInflater.from(mContext).inflate(R.layout.listitem_main, parent, false);
        } else {
            view = convertView;
        }
        TextView textView = (TextView) view.findViewById(R.id.item_main_text);
        textView.setText(result.getPois().get(position).getTitle());
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onItemClicklistener.callBack(result.getPois().get(position));
            }
        });
        return view;
    }
}

做法基本是这样,有什么不懂的可以在下面留言,还有一点需要注意的是关键字搜索的结果有些地方是没有经纬度的,所以返回之前需要判断,如果出现空指针现象,请在搜索结果点击回调之前判断非空

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值