首先先看到layout檔的排版:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/mView_Main" android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="你自己的key"> </com.google.android.maps.MapView> </LinearLayout>
很簡單的一個地圖畫面。
接下來先看一個類別物件,這是我用來存放每一個座標點的資訊。
package tw.tericky.test; public class ImageEntity { private int mLatitude; private int mLongitude; private String mName; public ImageEntity(int aLatitude, int aLongitude, String aName) { mLatitude = aLatitude; mLongitude = aLongitude; mName = aName; } public int getLatitude() { return mLatitude; } public void setLatitude(int aLatitude) { mLatitude = aLatitude; } public int getLongitude() { return mLongitude; } public void setmLongitude(int aLongitude) { mLongitude = aLongitude; } public String getName() { return mName; } public void setName(String aName) { mName = aName; } }
再來是關鍵的圖片放置層:
package tw.tericky.test; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import com.google.android.maps.GeoPoint; import com.google.android.maps.ItemizedOverlay; import com.google.android.maps.MapView; import com.google.android.maps.OverlayItem; public class ImageOverlay extends ItemizedOverlay<OverlayItem> { private static List<ImageEntity> mImageEntityList; // 存放座標點位的串列 private static int mBaseLevel = 10; // 圖片原大小對應的地圖縮放層級 private static float mLevelRate = 0.1f; // 每一級之間的縮放比例 private static float mScale = 1; // 存放計算後的縮放率 private static Drawable mDrawable; // Drawable物件 private static Bitmap mOriginalBmp; // 原本所用的圖示,設成全域變數避免每次重複生成 private Context mContext; // Context,不知道怎麼解釋 public ImageOverlay(Context aContext, List<ImageEntity> aImageEntityList, int aBaseLevel, float aLevelRate) { // 重點在這裡,把bind的drawable物件先設給mDrawable,再傳入做建構 super(mDrawable = boundCenterBottom(aContext.getResources().getDrawable(R.drawable.icon))); // 設定點位 setImageList(aImageEntityList); mContext = aContext; mBaseLevel = aBaseLevel; mLevelRate = aLevelRate; mOriginalBmp = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon); } @Override protected OverlayItem createItem(int i) { OverlayItem item = new OverlayItem(new GeoPoint(mImageEntityList.get(i).getLatitude(), mImageEntityList.get(i).getLongitude()), mImageEntityList.get(i).getName(), "Image"); // 要自己重新設定Market,否則沒有效果 item.setMarker(mDrawable); return item; } @Override public int size() { return mImageEntityList.size(); } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { // 計算縮放率,記得一定要 > 0 float scale = 1 - (mBaseLevel - mapView.getZoomLevel()) * mLevelRate; // 當比例不一樣的時候,再做設定,避免無謂的資源浪費 if (mScale != scale && scale > 0) { // 計算縮放後的長寬,一定要 >= 1,因為 < 1,轉成int後,就會是0,這樣就會錯誤 float scaleWidth = mOriginalBmp.getWidth() * scale; float scaleHeight = mOriginalBmp.getHeight() * scale; Bitmap newbmp = Bitmap.createScaledBitmap(mOriginalBmp, (int) scaleWidth, (int) scaleHeight, true); mDrawable = boundCenterBottom(new BitmapDrawable(mContext.getResources(), newbmp)); // 更新OverlayItem前,先把focus移走,不然會出錯 setLastFocusedIndex(-1); // 通知ItemizedOverlay更新OverlayItem populate(); // 儲存新的縮放率 mScale = scale; } super.draw(canvas, mapView, shadow); } // 設定點位串列 public void setImageList(List<ImageEntity> aImageEntityList) { if (aImageEntityList == null) { aImageEntityList = new ArrayList<ImageEntity>(); } else { mImageEntityList = aImageEntityList; } setLastFocusedIndex(-1); populate(); } }
再來看看怎麼呼叫使用:
package tw.tericky.test; import java.util.ArrayList; import java.util.List; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView; import android.os.Bundle; public class AndroidTestActivity extends MapActivity { private MapView mMapView; private ImageOverlay mImageOverlay; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 設定點位位置 List<ImageEntity> iEntityList = new ArrayList<ImageEntity>(); iEntityList.add(new ImageEntity(24405053, 120863250, "I1")); iEntityList.add(new ImageEntity(24004235, 120341400, "I2")); iEntityList.add(new ImageEntity(23398143, 120635284, "I3")); iEntityList.add(new ImageEntity(23539228, 121483978, "I4")); iEntityList.add(new ImageEntity(24244877, 121445526, "I5")); // 生成圖層 mImageOverlay = new ImageOverlay(AndroidTestActivity.this, iEntityList, 10, 0.1f); mMapView = (MapView) findViewById(R.id.mView_Main); // 加入圖層 mMapView.getOverlays().add(mImageOverlay); // 刷新 mMapView.invalidate(); // 設定有的沒的 mMapView.setBuiltInZoomControls(true); mMapView.setClickable(true); mMapView.setEnabled(true); mMapView.getController().setZoom(13); // zoom 到台灣 mMapView.getController().animateTo(new GeoPoint(23949024, 120992340)); } @Override protected boolean isRouteDisplayed() { return false; } }
這樣就大功告成了!簡單吧!
程式碼下載:androidTest.rar
延伸閱讀:Android - MapView上面的圖片跟著縮放 Part 2
沒有留言:
張貼留言