Android百度地图实现搜索和定位及自定义图标绘制并点击时弹出泡泡

一、问题描述

  上一次我们使用百度地图实现基本的定位功能,接下来我们继续实现搜索和定位,并使用LocationOverlay绘制定位位置,同时展示如何使用自定义图标绘制并点击时弹出泡泡

  如图所示:

二、编写MyApplication类

public class MyApplication extends Application {
private static MyApplication mInstance = null;
public boolean m_bKeyRight = true;
public BMapManager mBMapManager = null;
public static final String strKey = "申请的应用key";
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
initEngineManager(this);
}
public void initEngineManager(Context context) {
if (mBMapManager == null) {
mBMapManager = new BMapManager(context);
}
if (!mBMapManager.init(strKey,new MyGeneralListener())) {
Toast.makeText(MyApplication.getInstance().getApplicationContext(), "BMapManager 初始化错误!", Toast.LENGTH_LONG).show();
}
}
public static MyApplication getInstance() {
return mInstance;
}
// 常用事件监听,用来处理通常的网络错误,授权验证错误等
public static class MyGeneralListener implements MKGeneralListener {
@Override
public void onGetNetworkState(int iError) {
if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
Toast.makeText(MyApplication.getInstance().getApplicationContext(), "您的网络出错啦!",Toast.LENGTH_LONG).show();
}else if (iError == MKEvent.ERROR_NETWORK_DATA) {
Toast.makeText(MyApplication.getInstance().getApplicationContext(), "输入正确的检索条件!",Toast.LENGTH_LONG).show();
}
}
@Override
public void onGetPermissionState(int iError) {
//非零值表示key验证未通过
if (iError != 0) {
//授权Key错误:
Toast.makeText(MyApplication.getInstance().getApplicationContext(),
"请在 DemoApplication.java文件输入正确的授权Key,并检查您的网络连接是否正常!error: "+iError, Toast.LENGTH_LONG).show();
MyApplication.getInstance().m_bKeyRight = true;
}
else{
MyApplication.getInstance().m_bKeyRight = true;
//Toast.makeText(DemoApplication.getInstance().getApplicationContext(), "key认证成功", Toast.LENGTH_LONG).show();
}
}
}
}

三、编写MyLocationMapView,继承MapView重写onTouchEvent实现泡泡处理操作

public class MyLocationMapView extends MapView {

public static PopupOverlay pop = null;// 弹出泡泡图层,点击图标使用
public MyLocationMapView(Context context) {
super(context);
}
public MyLocationMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLocationMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!super.onTouchEvent(event)) {
// 消隐泡泡
if (pop != null && event.getAction() == MotionEvent.ACTION_UP)
pop.hidePop();
}
return true;
}
}

三、编写主程序MainActivity

  编写主程序MainActivity,用来展示如何结合定位SDK实现定位,并使用MyLocation Overlay绘制定位位置 同时展示如何使用自定义图标绘制并点击时弹出泡泡。

public class MainActivity extends Activity {
private EditText txtAddr;
// 定位相关
LocationClient mLocClient;
LocationData locData = null;
public MyLocationListenner myListener = new MyLocationListenner();
public MyApplication app;
//定位图层
locationOverlay myLocationOverlay = null;
//弹出泡泡图层
private PopupOverlay pop = null;//弹出泡泡图层,浏览节点时使用
private TextView popupText = null;//泡泡view
private View viewCache = null;
//地图相关,使用继承MapView的MyLocationMapView目的是重写touch事件实现泡泡处理
//如果不处理touch事件,则无需继承,直接使用MapView即可
public MyLocationMapView mMapView = null; // 地图View
private MapController mMapController = null;
private MKSearch mMKSearch = null;//用于信息检索服务
//UI相关
OnCheckedChangeListener radioButtonListener = null;
TextView requestLocButton ,btSerach;
boolean isRequest = false;//是否手动触发请求定位
boolean isFirstLoc = true;//是否首次定位
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 使用地图sdk前需先初始化BMapManager.
* BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,
* 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁
*/
app = (MyApplication)this.getApplication();
if (app.mBMapManager == null) {
app.mBMapManager = new BMapManager(getApplicationContext());
/**
* 如果BMapManager没有初始化则初始化BMapManager
*/
app.mBMapManager.init(MyApplication.strKey,new MyApplication.MyGeneralListener());
}
setContentView(R.layout.activity_main);
txtAddr=(EditText)findViewById(R.id.txtAddr);//关键字输入框
//监听搜索单击事件
btSerach= (TextView)findViewById(R.id.btOk);
btSerach.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mMKSearch.poiSearchInCity("", txtAddr.getText().toString());
}
});
//定位按钮
requestLocButton = (TextView)findViewById(R.id.btget);
requestLocButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
requestLocClick();
}
});
//地图初始化
mMapView = (MyLocationMapView)findViewById(R.id.bmapView);
mMapView.setTraffic(true);//设置地图模式为交通视图(也可为卫星视图)
mMapController = mMapView.getController();
mMapView.getController().setZoom(15);
mMapView.getController().enableClick(true);
mMapView.setBuiltInZoomControls(true);
//信息检索初始化
mMKSearch = new MKSearch();
mMKSearch.init(app.mBMapManager, new MKSearchListener() {
@Override
public void onGetAddrResult(MKAddrInfo arg0, int arg1) {
}
@Override
public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {
}
@Override
public void onGetDrivingRouteResult(MKDrivingRouteResult arg0,
int arg1) {
}
@Override
public void onGetPoiDetailSearchResult(int arg0, int arg1) {
}
@Override
public void onGetPoiResult(MKPoiResult res, int type, int error) {
if (error == MKEvent.ERROR_RESULT_NOT_FOUND) {
Toast.makeText(MainActivity.this, "抱歉,未找到结果",
Toast.LENGTH_LONG).show();
return;
} else if (error != 0 || res == null) {
Toast.makeText(MainActivity.this, "搜索出错啦.."+error,
Toast.LENGTH_LONG).show();
return;
}
PoiOverlay poiOverlay = new PoiOverlay(MainActivity.this,
mMapView);
poiOverlay.setData(res.getAllPoi());
mMapView.getOverlays().clear();
mMapView.getOverlays().add(poiOverlay);
mMapView.refresh();
for (MKPoiInfo info : res.getAllPoi()) {
if (info.pt != null) {
mMapView.getController().animateTo(info.pt);
break;
}
}
}
@Override
public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1,
int arg2) {
}
@Override
public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1){
}
@Override
public void onGetTransitRouteResult(MKTransitRouteResult arg0,
int arg1) {
}
@Override
public void onGetWalkingRouteResult(MKWalkingRouteResult arg0,
int arg1) {
}
});
createPaopao();
//定位初始化
mLocClient = new LocationClient( this );
locData = new LocationData();
mLocClient.registerLocationListener( myListener );
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);//打开gps
option.setAddrType("all");//返回的定位结果包含地址信息
option.disableCache(false);//禁止启用缓存定位
option.setCoorType("bd09ll"); //设置坐标类型
option.setScanSpan(1000);
mLocClient.setLocOption(option);
mLocClient.start();
//定位图层初始化
myLocationOverlay = new locationOverlay(mMapView);
//设置定位数据
myLocationOverlay.setData(locData);
//添加定位图层
mMapView.getOverlays().add(myLocationOverlay);
myLocationOverlay.enableCompass();
//修改定位数据后刷新图层生效
mMapView.refresh();
}
/**
* 手动触发一次定位请求
*/
public void requestLocClick(){
isRequest = true;
mLocClient.requestLocation();
Toast.makeText(MainActivity.this, "正在定位……", Toast.LENGTH_SHORT).show();
}
/**
* 创建弹出泡泡图层
*/
public void createPaopao(){
viewCache = getLayoutInflater().inflate(R.layout.custom_text_view, null);
popupText =(TextView) viewCache.findViewById(R.id.textcache);
//泡泡点击响应回调
PopupClickListener popListener = new PopupClickListener(){
@Override
public void onClickedPopup(int index) {
}
};
pop = new PopupOverlay(mMapView,popListener);
MyLocationMapView.pop = pop;
}
/**
* 定位SDK监听函数
*/
public class MyLocationListenner implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null)
return ;
locData.latitude = location.getLatitude();
locData.longitude = location.getLongitude();
//如果不显示定位精度圈,将accuracy赋值为0即可
locData.accuracy = location.getRadius();
// 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
locData.direction = location.getDerect();
//更新定位数据
myLocationOverlay.setData(locData);
//更新图层数据执行刷新后生效
mMapView.refresh();
//是手动触发请求或首次定位时,移动到定位点
if (isRequest || isFirstLoc){
//移动地图到定位点
//Log.d("LocationOverlay", "receive location, animate to it");
mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6)));
isRequest = false;
myLocationOverlay.setLocationMode(LocationMode.FOLLOWING);
}
//首次定位完成
isFirstLoc = false;
}
public void onReceivePoi(BDLocation poiLocation) {
if (poiLocation == null){
return ;
}
}
}
//继承MyLocationOverlay重写dispatchTap实现点击处理
public class locationOverlay extends MyLocationOverlay{
public locationOverlay(MapView mapView) {
super(mapView);
}
@Override
protected boolean dispatchTap() {
//处理点击事件,弹出泡泡
popupText.setBackgroundResource(R.drawable.popup);
popupText.setText(mLocClient.getLastKnownLocation().getAddrStr());
pop.showPopup(BMapUtil.getBitmapFromView(popupText),new GeoPoint((int)(locData.latitude*1e6), (int)(locData.longitude*1e6)),8);
return true;
}
}
@Override
protected void onPause() {
mMapView.onPause();
if(app.mBMapManager!=null){
app.mBMapManager.stop();
}
super.onPause();
}
@Override
protected void onResume() {
mMapView.onResume();
if(app.mBMapManager!=null){
app.mBMapManager.start();
}
super.onResume();
}
@Override
protected void onDestroy() {
//退出时销毁定位
if (mLocClient != null)
mLocClient.stop();
mMapView.destroy();
if(app.mBMapManager!=null){
app.mBMapManager.destroy();
app.mBMapManager=null;
}
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mMapView.onRestoreInstanceState(savedInstanceState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
}

MainActivity的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.jerehedu.ljb.MyLocationMapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="@drawable/edit_bg_all" >
<EditText
android:id="@+id/txtAddr"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:layout_marginRight="2dp"
android:layout_toLeftOf="@+id/btOk"
android:background="@drawable/edit_bg_all"
android:completionThreshold="2"
android:drawableLeft="@drawable/qz_icon_seabar_search"
android:hint="请输入搜索关键字" />
<TextView
android:id="@+id/btOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="2dp"
android:layout_toLeftOf="@+id/s2"
android:text="搜索"
android:textSize="18sp" />
<ImageView
android:id="@+id/s2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="2dp"
android:layout_toLeftOf="@+id/btget"
android:src="@drawable/slide_center" />
<TextView
android:id="@+id/btget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="定位"
android:textSize="18sp" />
</RelativeLayout>
</FrameLayout>
</RelativeLayout>

通过以上内容给大家分享了Android百度地图实现搜索和定位及自定义图标绘制并点击时弹出泡泡的相关知识,希望对大家有所帮助。

(0)

相关推荐

  • Android开发笔记之:在ImageView上绘制圆环的实现方法

    绘制圆环其实很简单,有大概以下三种思路. 这里先说网上提到的一种方法.思路是先绘制内圆,然后绘制圆环(圆环的宽度就是paint设置的paint.setStrokeWidth的宽度),最后绘制外圆.请看核心源码: 复制代码 代码如下: <SPAN xmlns="http://www.w3.org/1999/xhtml">package yan.guoqi.rectphoto;import android.content.Context;import android.graph

  • Android开发中使用achartengine绘制各种图表的方法

    本文实例讲述了Android开发中使用achartengine绘制各种图表的方法.分享给大家供大家参考,具体如下: 1. ABarChart.java package com.anjoyo.achartengine; import java.util.Random; import org.achartengine.ChartFactory; import org.achartengine.chart.BarChart.Type; import org.achartengine.model.Cat

  • Android编程绘制圆形图片的方法

    本文实例讲述了Android编程绘制圆形图片的方法.分享给大家供大家参考,具体如下: 效果图如下: 第一步:新建RoundView自定义控件继承View package com.rong.activity; import com.rong.test.R; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.grap

  • 解决Android SurfaceView绘制触摸轨迹闪烁问题的方法

    本文分享了解决SurfaceView触摸轨迹闪烁问题的方法,供大家参考,具体内容如下 第一种解决SurfaceView触摸轨迹闪烁问题的方法: 由于SurfaceView使用双缓存机制,两张画布轮流显示到屏幕上.那么,要存储触摸轨迹并避免两张画布内容不一致造成的闪烁问题,完全可以利用保存绘制过程并不断重新绘制的方法解决闪烁,而且这样还顺带解决了多次试验中偶尔出现的因为moveTo()函数不能读取到参数执行默认设置(参数设为上次的触摸点)而出现的断线连接闪烁问题,详细代码如下: package c

  • Android自定义View之继承TextView绘制背景

    本文实例为大家分享了TextView绘制背景的方法,供大家参考,具体内容如下 效果: 实现流程: 1.初始化:对画笔进行设置 mPaintIn = new Paint(); mPaintIn.setAntiAlias(true); mPaintIn.setDither(true); mPaintIn.setStyle(Paint.Style.FILL); mPaintIn.setColor(getResources().getColor(R.color.colorPrimary)); mPain

  • Android listView 绘制表格实例详解

    Android  listView 绘制表格 效果图: 二,创建步骤: 1,创建布局: activity_main中的布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:

  • Android编程开发之在Canvas中利用Path绘制基本图形(圆形,矩形,椭圆,三角形等)

    本文实例讲述了Android编程开发之在Canvas中利用Path绘制基本图形的方法.分享给大家供大家参考,具体如下: 在Android中绘制基本的集合图形,本程序就是自定义一个View组件,程序重写该View组件的onDraw(Canvase)方法,然后在该Canvas上绘制大量的基本的集合图形. 直接上代码: 1.自定义的View组件代码: package com.infy.configuration; import android.content.Context; import andro

  • Android中使用achartengine生成图表的具体方法

    今天在做项目的时候用到了图表功能,记录下来 achartengine是google的一个开源项目,可以在https://code.google.com/p/achartengine/ 下载技术文档,jar包以及项目源代码 demo下载:https://code.google.com/p/achartengine/downloads/list 一.饼状图 新建工程,添加achartengine  jar包 PieChart.java 复制代码 代码如下: package com.meritit.f

  • Android开发 OpenGL ES绘制3D 图形实例详解

    OpenGL ES是 OpenGL三维图形API 的子集,针对手机.PDA和游戏主机等嵌入式设备而设计. Ophone目前支持OpenGL ES 1.0 ,OpenGL ES 1.0 是以 OpenGL 1.3 规范为基础的,OpenGL ES 1.1 是以 OpenGL 1.5 规范为基础的.本文主要介绍利用OpenGL ES绘制图形方面的基本步骤. 本文内容由三部分构成.首先通过EGL获得OpenGL ES的编程接口;其次介绍构建3D程序的基本概念;最后是一个应用程序示例. OpenGL E

  • Android QQ登录界面绘制代码

    先看看效果图: 首先过程中碰到的几个问题: 1.对 EditText 进行自定义背景 2.运行时自动 EditText 自动获得焦点 3.在获得焦点时即清空 hint ,而不是输入后清空 4.清空按钮的出现时机(在得到焦点并且有输入内容时) ---  这些问题都有一一解决 --- 以下是代码: 布局 fragment_main(问题2) <!-- android:focusable="true" android:focusableInTouchMode="true&qu

  • Android中使用ListView绘制自定义表格技巧分享

    先上一下可以实现的效果图  要实现的效果有几方面 1.列不固定:可以根据数据源的不同生成不同的列数 2.表格内容可以根据数据源的定义合并列 3.要填写的单元格可以选择自定义键盘还是系统键盘 奔着这三点,做了个简单的实现,把源码贴一下(因为该点是主界面中的一部分,不便于放整个Demo) 自定义适配器,CallBackInterface是自定义的回调接口,这里定义回调是因为数据输入时需要及时保存 复制代码 代码如下: public class SiteDetailViewAdapter extend

随机推荐