`
yuanlanjun
  • 浏览: 1188107 次
文章分类
社区版块
存档分类
最新评论

Google Map 实战 :漂亮的气泡地图

 
阅读更多

准备工作就是下载谷歌提供的架包,下载地址是:http://code.google.com/p/ksoap2-android/downloads/detail?name=ksoap2-android-assembly-2.4-jar-with-dependencies.jar&can=2&q=大家自己下载,然后导入到工程里面,对了,建立工程时候,版本要 x.x google api的。

第一步,现在写layout目录下一个main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.google.android.maps.MapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:apiKey="0aVeWdF7g8mo7Q-S3rDHcpmANgEF9752OHJlh0g"
        android:clickable="true"
        android:state_enabled="true" />

</LinearLayout>

第二步,用来创建一个显示气泡视图的view.xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/pop" >

    <TextView
        android:id="@+id/map_bubbleTitle"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:gravity="center_horizontal"
        android:singleLine="true" />

    <ImageView
        android:id="@+id/map_bubbleImage"
        android:layout_width="30dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/map_bubbleTitle" />

    <TextView
        android:id="@+id/map_bubbleText"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/map_bubbleTitle"
        android:singleLine="false" />

</RelativeLayout>
第三步,自定义一个ItemizedOverlay用来表示景点的图片和文字的图层,主要针对该图层进行重新绘制,达到想要的效果

package mars.com;

import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;

public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {

	private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>();
	private Context context;

	public MyItemizedOverlay(Drawable defaultMarker, Context context) {
		super(defaultMarker);
		this.context = context;
	}

	public void addOverlay(OverlayItem overlay) {
		overlayItemList.add(overlay);
		populate();// 增加新的的overlay一定要使用这个方法,它会读出每一个overlay并准备它被贴上
	}

	@Override
	protected OverlayItem createItem(int i) {
		return overlayItemList.get(i);
	}

	@Override
	public int size() {
		return overlayItemList.size();
	}

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, shadow);
		// projection接口用于屏幕像素点坐标系统和地球表面经纬度点坐标之间的转换
		Projection projection = mapView.getProjection();
		// 遍历所有的OverlayItem
		for (int index = this.size() - 1; index > 0; index--) {
			// 得到给定索引的item
			OverlayItem overlayItem = getItem(index);
			// 把经纬度变换到相对于mapview左上角的车屏幕像素坐标
			Point point = projection.toPixels(overlayItem.getPoint(), null);
			Paint paintText = new Paint();
			paintText.setColor(Color.RED);
			paintText.setTextSize(13);
			// 绘制文本
			canvas.drawText(overlayItem.getTitle(), point.x + 10, point.y - 15,
					paintText);
		}

	}

	@Override
	protected boolean onTap(int index) {
		setFocus(overlayItemList.get(index));
		return super.onTap(index);
	}

}
第四步,实现自己的activity先在地图上根据经纬度创建位置,并且自定义图片和文字进行表示,给自定义的iitemizedoverlay添加焦点改变事件监听,并完成气泡view的显示效果。

package mars.com;

import java.util.List;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MapView.LayoutParams;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class GoogleMapDemoActivity extends MapActivity {

	private MapView mapview;
	private View popView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mapview = (MapView) findViewById(R.id.mapview);
		mapview.setBuiltInZoomControls(true);
		// 贴上标记
		popView = View.inflate(this, R.layout.view, null);
		mapview.addView(popView, new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT, null,
				MapView.LayoutParams.BOTTOM_CENTER));// 由于气泡下边居中,所以设置BOTTOM_CENTER
		// 这里没有给GeoPoint在onfocusChangeListener中设置
		popView.setVisibility(View.GONE);
		// 创建图标资源
		Drawable drawable = this.getResources().getDrawable(
				R.drawable.ic_launcher);
		// 为标记定义边界
		drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
				drawable.getIntrinsicHeight());
		MyItemizedOverlay overlay = new MyItemizedOverlay(drawable, this);
		overlay.setOnFocusChangeListener(onFocusChangeListener);
		// 构造一个经纬点,深圳世界之窗
		GeoPoint point = new GeoPoint((int) (22.5348 * 1E6),
				(int) (113.97246 * 1E6));
		OverlayItem overlayItem = new OverlayItem(point, "世界之窗",
				"大型文化旅游景区,是深圳著名的旅游景点");
		overlay.addOverlay(overlayItem);
		// 第二个标记,锦绣中华
		point = new GeoPoint((int) (22.5308 * 1E6), (int) (113.99151 * 1E6));
		overlayItem = new OverlayItem(point, "锦绣中华",
				"中国旅游胜地四十佳之一,是目前世界上最大的实景微缩景区,已经入选中国世界记录协会的候选世界记录");
		overlay.addOverlay(overlayItem);
		// 添加自定义的ItemizedOvewrlay
		List<Overlay> mapOverlays = mapview.getOverlays();
		mapOverlays.add(overlay);
		// 设置地图模式为交通模式
		mapview.setStreetView(true);
		// 取得地图控制器对象,用于控制mapView
		mapview.getController().setCenter(point);
		// 设置默认缩放级别
		mapview.getController().setZoom(15);

	}

	// 当一个overlay焦点发生改变的时候触发
	private final ItemizedOverlay.OnFocusChangeListener onFocusChangeListener = new ItemizedOverlay.OnFocusChangeListener() {

		public void onFocusChanged(ItemizedOverlay overlay, OverlayItem newFocus) {
			if (popView != null) {
				popView.setVisibility(View.GONE);
			}
			if (newFocus != null) {
				MapView.LayoutParams geoLP = (LayoutParams) popView
						.getLayoutParams();
				geoLP.point = newFocus.getPoint();// 用于popView的定位
				TextView title = (TextView) popView
						.findViewById(R.id.map_bubbleTitle);
				title.setText(newFocus.getTitle());

				TextView desc = (TextView) popView
						.findViewById(R.id.map_bubbleText);
				if (newFocus.getSnippet() == null) {
					desc.setVisibility(View.GONE);
				} else {
					desc.setVisibility(View.VISIBLE);
					desc.setText(newFocus.getSnippet());
				}
				mapview.updateViewLayout(popView, geoLP);
				popView.setVisibility(View.VISIBLE);
			}
		}

	};

	@Override
	protected boolean isRouteDisplayed() {// 是否导航
		return false;// 不导航
	}
}
第五步,别忘了加权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="mars.com"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".GoogleMapDemoActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <uses-library android:name="com.google.android.maps" />
    </application>

</manifest>


后记,我用真机上测试过了,可以使用,但是有一点我不太明白,为什么速度有点慢呢,我可是用的无线网呀(上网页超级快的),缩放的时候,总是等几秒,它的页面才会打开,让人很郁闷,不知道什么情况,不如我的上一个小例子,速度来的快。其他地方倒是没有任何问题。大家作为参考吧。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics