2010-01-13 22:35 墳墓 (Brian Hsu)
話說這兩天想到一些 Android 加 Google Maps 的應用,於是試著想用 Scala 試著做做看,沒想到竟然遇到了一堆問題,以致於陷入了苦戰之中。
簡單的來講,造成這次的狀況的原因,有以下兩個
- Scala 的編譯器有蟲,當某個 Java 函式庫參照到另一個 Java 函式庫的 static inner class 時,就會找不到而爆炸。這次爆炸的原因就是 MapView 裡面用了 ViewGroup.LayoutParams。
- Scala 因為語意上的關係,沒有 static 這種東西,以致於無法存取 static protected 的方法,所以 ItemizedOverlay 又不能用了。
結論:兩個最重要的東西都不能用啊!
為了解決這個問題,我只好自己寫一個 Wrapper,並且把他包成函式庫的形式,方便以後使用,或者以防有人遇到和我一樣的狀況卻求助無門,程式碼和說明在 GitHub 上。
總之,目前總算是把 Hello, MapView 的範例跑起來了,程式碼如下,看起來和原來 Java 的版本差不多,這樣的 Wrapper 應該算還可以吧?
package org.bone;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ZoomControls;
import android.widget.LinearLayout;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Overlay;
import org.maidroid.scalamap.SMapView
class HelloMap extends MapActivity
{
private lazy val layout = findViewById (R.id.zoomview).
asInstanceOf[LinearLayout]
private lazy val mapView = new SMapView (findViewById(R.id.mapview))
private lazy val mapOverlays = mapView.getOverlays
private lazy val drawable = getResources.
getDrawable (R.drawable.androidmarker)
private lazy val itemizedoverlay = new HelloItemizedOverlay (drawable)
override def isRouteDisplayed = false
override def onCreate(savedInstanceState: Bundle)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
mapView.setBuiltInZoomControls (true)
val point1 = new GeoPoint (19240000, -99120000)
val point2 = new GeoPoint(35410000, 139460000)
val overlayitem1 = new OverlayItem (point1, "", "")
val overlayitem2 = new OverlayItem (point2, "", "")
itemizedoverlay.addOverlay (overlayitem1)
itemizedoverlay.addOverlay (overlayitem2)
mapOverlays.add (itemizedoverlay)
}
}
package org.bone
import android.graphics.drawable.Drawable
import com.google.android.maps.OverlayItem
import java.util.ArrayList
import org.maidroid.scalamap.SItemizedOverlay
import SItemizedOverlay.BOUND_CENTER_BOTTOM
class HelloItemizedOverlay (drawable: Drawable) extends
SItemizedOverlay[OverlayItem] (drawable, BOUND_CENTER_BOTTOM)
{
private lazy val mOverlays = new ArrayList[OverlayItem]
override def createItem (i: Int) = mOverlays.get(i)
override def size () = mOverlays.size()
def addOverlay (overlay: OverlayItem)
{
mOverlays.add (overlay);
populate ();
}
}

回響